简体   繁体   English

我可以使用class属性作为实例方法的默认值吗?

[英]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一个重要的事情是classdef看到的 ,不只是保存起来供以后语句被执行。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM