Python类声明中的变量用法

时间:2012-10-16 23:05:11

标签: python class variables

以下是Zed Shaw的“学习Python困难之路”教程40的代码片段:

class Song(object):

    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print line

为什么Python在定义“sing_me_a_song”函数时允许使用“self.lyrics”?是因为无论变量 在“ init ”下定义,也可以在同一个类的其他地方使用?

感谢。

6 个答案:

答案 0 :(得分:5)

实例变量

这称为实例变量。使用self.定义为“前缀”的任何变量都可以在对象的任何方法中使用。通常这些变量是在__init__中创建的,因此可以从初始化对象的那一刻开始访问它们,尽管您可以在其他方法中定义实例变量。例如:

>>> class foo:
...     def fun(self):
...             self.heh=3
... 
>>> f = foo()
>>> f.heh 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: foo instance has no attribute 'heh'
>>> f.fun()
>>> f.heh
3

注意初始化__init__之外的实例变量的危险;如果在尝试访问它们之前未调用它们的初始化方法,则会出现错误。

类变量

这不要与“类变量”混淆,“类变量”是可以由类的任何方法访问的另一种类型的变量。可以为整个类设置类变量,而不仅仅是该类的特定对象。这是一个带有实例和类变量的示例类来显示差异:

class MyClass:
    classVar = "I'm a class var."
    def __init__(self):
        self.instanceVar = "I'm an instance var."
    def fun(self):
        methodVar = "I'm a method var; I cannot be accessed outside of this method."
        self.instanceVar2 = "I'm another instance var, set outside of __init__."

关于“方法”与“功能”的说明

在您的问题中,您将sing_me_a_song称为“功能”。实际上,它是类Song方法。这与常规旧函数不同,因为它基本上与类相关联,因此也与该类的对象相关联。

答案 1 :(得分:1)

定义 init 函数时,您会注意到第一个参数是“self” - 这是对正在创建的对象的引用。当你执行“self.lyrics = lyrics”时,这实际上是将值赋给对象的属性,而不是变量。

所以,当你去其他地方访问它时,它是可见的 - 但不是因为它是一个变量!你是否正确地认为,如果我们遵循正常的范围规则,它就不应该是可见的。但是,它不是变量,任何代码都可以访问self.lyrics的值,只要它们具有对象的引用。

e.g:

test = Song(["This is some lyrics."])
test.sing_me_a_song() #this works
print test.lyrics[0] #but so does this!

答案 2 :(得分:0)

根据代码,self.lyrics在类的构造函数中定义。在创建对象时始终首先调用构造函数。 self.lyrics可以在其他类方法中使用。

答案 3 :(得分:0)

self用于指代调用该方法的Song类的实际实例。例如,如果你这样做......

foo = Song("hello")
bar = Song("world")

然后foo.lyrics设置为"hello"bar.lyrics设置为"world"。如果你然后在其中一个实例上调用一个方法,就像这样......

foo.sing_me_a_song()

然后调用此方法,self设置为fooself.lyrics查找"hello",因为它是foo中有lyrics的实例{1}}设置为"hello"

答案 4 :(得分:0)

重要的是要意识到它不是类定义,与java或c ++定义类的方式完全相同。

自我是一个动态的对象。无论是自我还是任何其他对象, myObj.newField = value 总是有效的。 因为初始化对象时运行 init ,所以有一个self.lyrics元素。

你可以


def foo(self):
    self.thing = "turtle"

然后在foo之后调用的任何函数中,你可以引用self.thing。 (这可能是一个非常糟糕的主意,但它在语法上没有任何错误)。

答案 5 :(得分:0)

名称self并不特别。在python中,对象的每个方法都自动引用该对象作为它的第一个参数。

这意味着在__init__(构造函数)方法中,您在对象上设置属性lyrics。稍后,您可以调用sing_me_a_song,这将获得对具有lyrics属性的同一对象的引用。