-2

第一个示例中的方法在未定义__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

4

2 回答 2

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通过doing调用的变量self.foo = 'K-Dawg'。这就是为什么它有效。

于 2013-10-12T05:54:25.940 回答
2

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

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

def __init__(self):
    self.foo = 'K-Dawg'
于 2013-10-12T05:43:55.723 回答