1

这是 Zed Shaw 的“Learn Python the Hard Way”教程 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 ”下定义的任何变量也可以在同一类的其他地方使用吗?

谢谢。

4

6 回答 6

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。这与常规的旧函数不同,因为它从根本上与类相关联,因此也与该类的对象相关联。

于 2012-10-16T23:06:39.547 回答
1

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

所以当你去别处访问它时,它是可见的——但不是因为它是一个变量!你的想法是对的,如果我们遵循正常的范围规则,它不应该是可见的。但是,它不是变量,任何代码都可以访问 self.lyrics 的值,只要它们具有对对象的引用。

例如:

test = Song(["This is some lyrics."])
test.sing_me_a_song() #this works
print test.lyrics[0] #but so does this!
于 2012-10-16T23:10:48.223 回答
0

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

于 2012-10-16T23:09:11.030 回答
0

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

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

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

foo.sing_me_a_song()

self然后使用set to调用该方法foo,并因此self.lyrics查找,"hello"因为它是foo其中lyrics设置为的实例"hello"

于 2012-10-16T23:10:01.167 回答
0

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

自我是一个动态的对象。无论是自我,还是任何其他对象, myObj.newField = value 始终是一件有效的事情。由于在初始化对象时运行了init,因此有一个 self.lyrics 元素。

你可以有


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

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

于 2012-10-16T23:10:43.120 回答
0

这个名字self没什么特别的。在 python 中,对象的每个方法都会自动引用该对象作为它的第一个参数。

This means that in the __init__ (constructor) method, your setting the attribute lyrics on the object. Later on, you can call sing_me_a_song, and that will get a reference to the same object with lyrics attribute.

于 2012-10-16T23:10:53.010 回答