[英]Can I use a class attribute as a default value for an instance method?
I would like to use a class attribute as a default value for one of the arguments to my class's __init__
method. 我想使用class属性作为我的类的__init__
方法的一个参数的默认值。 This construct raises a NameError
exception, though, and I don't understand why: 但是,这个构造引发了一个NameError
异常,我不明白为什么:
class MyClass():
__DefaultName = 'DefaultName'
def __init__(self, name = MyClass.__DefaultName):
self.name = name
Why does this fail, and is there a way to do this that works? 为什么这会失败,有没有办法做到这一点?
That's because, according to the documentation : 那是因为,根据文件 :
Default parameter values are evaluated when the function definition is executed. 执行函数定义时,将评估默认参数值。 This means that the expression is evaluated once, when the function is defined 这意味着在定义函数时,表达式将被计算一次
When __init__()
is defined, the definition of MyClass
is incomplete, as it's still being parsed, so you can't refer to MyClass.__DefaultName
yet. 当__init__()
被定义时, MyClass
的定义是不完整的,因为它仍然被解析,所以你不能引用MyClass.__DefaultName
。 One way to work around that is to pass a special unique value to __init__()
, such as None
: 解决这个问题的一种方法是将一个特殊的唯一值传递给__init__()
,例如None
:
def __init__(self, name=None):
if name is None:
name = MyClass.__DefaultName
# ...
An important thing to keep in mind with Python is when different bits of code are executed, along with the fact that class
and def
statements are executed when seen , not just stored away for later. 当不同的代码位执行的,与事实一起记住与Python一个重要的事情是class
和def
时看到的 ,不只是保存起来供以后语句被执行。 With a def
it's a little easier to understand because the only thing being executed is whatever is between the ()
s -- so in your code above 使用def
它更容易理解,因为唯一被执行的是()
s之间的任何内容 - 所以在上面的代码中
def __init__( SELF, name = MyClass.__DefaultName ):
when Python sees MyClass.__DefaultName
it tries to find it first in the local
namespace, then the module (aka global
) namespace, and finally in builtins
. 当Python看到MyClass.__DefaultName
时,它首先尝试在local
命名空间中找到它,然后在模块(也称为global
)命名空间中找到它,最后在builtins
命令中找到它。
What is the local
namespace when executing a class
statement? 执行class
语句时, local
命名空间是什么? That's the fun part -- it is what will become the class
namespace, but at the moment it is anonymous -- so you can't reference it by name (aka MyClass
in your code) but you can directly reference anything that has already been defined... and what has been defined? 这是有趣的部分 - 它将成为class
命名空间,但目前它是匿名的 - 所以你不能通过名称引用它(在代码中也称为MyClass
),但你可以直接引用任何已经存在的东西定义了......以及定义了什么? In your class example only one thing -- __DefaultName
. 在你的类示例中只有一件事__DefaultName
。 So your __init__
should look like this: 所以你的__init__
应该是这样的:
def __init__( SELF, name=__DefaultName ):
Keep in mind that you can't change MyClass._MyClass__DefaultName
later and have those changes show up in new instances. 请记住,您以后无法更改MyClass._MyClass__DefaultName
并在新实例中显示这些更改。 Why? 为什么? Because the __init__
def is executed only once, and whatever value __DefaultName
had at that moment has been stored away and will always be used -- unless you directly specify a new value when you create a new instance: 因为__init__
def只执行一次,并且__DefaultName
在那一刻所拥有的值已被存储并且将始终被使用 - 除非您在创建新实例时直接指定新值:
my_instance = MyClass(name='new name')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.