类构造函数对其属性的影响

时间:2013-10-12 05:41:09

标签: python python-2.7 constructor

第一个示例中的__str__方法如何在未定义self.foo时成功返回字符串:

class foo:
    foo = 'K-Dawg'

    def __str__(self):
        return self.foo

obj = foo()
print obj
#K-Dawg

当我创建一个类构造函数方法 __init__ 时,这会产生:

  

AttributeError:foo实例没有属性'foo'

class foo:
    def __init__(self):
        foo = 'K-Dawg'

    def __str__(self):
        return self.foo

obj = foo()
print obj

为什么在第一个示例中成功返回self.foo而在第二个示例中没有成功返回?

类构造函数对其属性有什么影响?

修改: 我知道将foo = 'K-Dawg'更改为self.foo = 'K-Dawg'会成功打印 K-Dawg ,但我问的是为什么第一个属性foo可以使用self.foo

调用示例

2 个答案:

答案 0 :(得分:6)

修改后的第一个程序

class foo:
    foo = 'K-Dawg'

    def __str__(self):
        print dir(self)
        return self.foo

obj = foo()
print obj

修改后的第二个程序

class foo:
    def __init__(self):
        print locals()
        foo = 'K-Dawg'
        print locals()

    def __str__(self):
        print locals()
        return self.foo

obj = foo()
print obj

我刚刚包含了一些印刷语句。如果你查看每个程序的输出,你将能够弄清楚究竟发生了什么。

第一个程序将打印

['__doc__', '__module__', '__str__', 'foo']
K-Dawg

我们可以看到foo已存在于对象中。实际上,在这种情况下,foo是一个类变量(与类实例无关。如果你来自C,C ++或JAVA背景,这可以被认为是一个静态变量,它被绑定到一个类而不是一个对象。)

第二个程序将打印

{'self': <__main__.foo instance at 0x7f528aa90488>}
{'self': <__main__.foo instance at 0x7f528aa90488>, 'foo': 'K-Dawg'}
{'self': <__main__.foo instance at 0x7f11f236d488>}
AttributeError: foo instance has no attribute 'foo'

它显然向我们显示变量foo已在__init__函数中创建,但在到达__str__时无效。这意味着在foo中创建的__init__变量是该函数的本地变量。

如果你想在对象中创建变量,你应该做这样的事情

class foo:
    def __init__(self):
        print locals()
        self.foo = 'K-Dawg'   # Note the self keyword at the beginning
        print locals()

    def __str__(self):
        print locals()
        return self.foo

obj = foo()
print obj

<强>输出

{'self': <__main__.foo instance at 0x7fe0e2da24d0>}
{'self': <__main__.foo instance at 0x7fe0e2da24d0>}
{'self': <__main__.foo instance at 0x7fe0e2da24d0>}
K-Dawg

self指向类的当前实例,我们通过执行foo附加名为self.foo = 'K-Dawg'的变量。这就是为什么这样做的原因。

答案 1 :(得分:2)

在第一个示例中,您创建了一个类属性foo ---在该类的所有实例之间共享一个属性。当您尝试访问self.foo时,如果实例没有自己的foo属性,则会从类中读取该属性。

在第二种情况下,您根本不创建属性。 foo中的__init__只是一个局部变量。如果要创建实例变量,则需要:

def __init__(self):
    self.foo = 'K-Dawg'