繁体   English   中英

Python类声明中的变量用法

[英]Variable Usage in Python Class Declaration

这是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

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

谢谢。

实例变量

这称为实例变量。 self.定义的任何变量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类的一种方法 这与常规的旧函数不同,因为它从根本上与类相关联,因此也与该类的对象相关联。

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

因此,当您随后在其他地方访问它时,它是可见的-但不是因为它是变量! 您认为我们遵循正常的作用域规则是正确的,它应该不可见。 但是,它不是变量,并且任何代码都可以访问self.lyrics的值,只要它们具有对该对象的引用即可。

例如:

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

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

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

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

然后foo.lyrics设置为"hello" ,而bar.lyrics设置为"world" 如果您随后在这些实例之一上调用方法,就像这样...

foo.sing_me_a_song()

然后在self设置为foo情况下调用该方法,因此self.lyrics查找"hello"因为foo中的实例的lyrics设置为"hello"

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

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

你可以有


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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM