python类属性不能用作构造函数的参数?

时间:2015-09-24 13:04:59

标签: python class constructor arguments class-attributes

在python 3中,我发现class属性可以用作__init__()函数中的参数,如下所示:

file test.py:

class Foo:
    var1 = 23333
    def __init__(self, var=var1):
        self.var = var

在cmd中运行:

C:\Users\rikka\Desktop>py -3 -i test.py
>>> f1=Foo()
>>> f1.var
23333

但是通过使用dot.expression,当init这个类时,解释器将报告错误:

file test2.py:

class Foo:
    var1 = 23333
    def __init__(self, var=Foo.var1):
       self.var = var

在cmd中运行:

C:\Users\rikka\Desktop>py -3 -i test2.py
Traceback (most recent call last):
  File "test2.py", line 1, in <module>
    class Foo:
  File "test2.py", line 3, in Foo
    def __init__(self, var=Foo.var1):
NameError: name 'Foo' is not defined

我只是不知道为什么口译员找不到名字&#39; Foo&#39;因为Foo是环境中全局框架中的名称。有什么关于python类的范围相关的概念,我不完全理解?

2 个答案:

答案 0 :(得分:6)

函数默认值设置为函数定义时间,而不是在被调用时。因此,不是存储的表达式var1,而是变量所代表的23333。在定义函数时,var1恰好是局部变量,因为在构建类时,类主体中的所有名称都被视为函数中的本地变量,但名称为{{1尚未存在,因为该类还没有完成构建。

改为使用sentinel,并在函数体中使用,然后确定Foo的当前值:

Foo.var1

我在这里使用def __init__(self, var=None): if var is None: var = Foo.var1 self.var = var 作为哨兵,因为它很容易获得并且通常不需要作为实际值。如果您确实需要将None设置为不同的(即非默认值),请使用不同的单一标记:

var

答案 1 :(得分:1)

问题是你在构建过程中试图引用Foo。在定义Foo.__init__时,即Foo.var被评估的时刻,Foo尚不存在(因为它的方法,即Foo.__init__本身,还没有完全建成。)

在函数/方法定义期间解析函数/方法默认参数。类只有在定义后才可用。如果类方法定义(即参数)引用类本身,则会获得循环依赖。没有类就不能定义该方法,如果没有它的方法就不能定义类。

请参阅Martijn Pieters关于如何实际处理此类依赖关系的回复。