理解python类属性
我对编程非常陌生,并开始学习python。这个问题可能看起来很愚蠢,所以请原谅我的无知。 考虑下面的代码片段:理解python类属性,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我对编程非常陌生,并开始学习python。这个问题可能看起来很愚蠢,所以请原谅我的无知。 考虑下面的代码片段: class Test1: bar = 10 def display(self,foo): self.foo=foo print "foo : ",self.foo #80 def display1(self): print "bar: ", self.bar #10 print "again
class Test1:
bar = 10
def display(self,foo):
self.foo=foo
print "foo : ",self.foo #80
def display1(self):
print "bar: ", self.bar #10
print "again foo: ", self.foo #80
if __name__ == '__main__':
test1 = Test1()
test1.display(80)
test1.display1()
print test1.bar #10
print test1.foo #80
我想了解使用foo和bar(wrt到我们定义它们的地方)之间的区别是什么,因为在范围方面,它们在所有地方都可以平等地访问,彼此比较,唯一的区别是一个在函数内部,另一个在类内部,但它们仍然是“实例”变量。
那么哪一个是好的实践呢
另外,如果我稍微修改一下显示功能,如下所示:
def display(self,foo):
self.foo=foo
foo = foo
print "self.foo : ",self.foo
print "foo : ",foo
有人能解释一下python是如何看待这一点的,因为这个
self
关键字在两个foo
bar
是一个类属性,而foo
是一个实例属性之间带来了什么区别/意义吗。主要区别在于,bar
将可用于所有类实例,而foo
仅当您在某个实例上调用display时才可用于该实例
>>> ins1 = Test1()
ins1.bar
工作正常,因为它是一个类属性,由所有实例共享
>>> ins1.bar
10
但您不能在此处直接访问foo,因为它尚未定义:
>>> ins1.foo
Traceback (most recent call last):
File "<ipython-input-62-9495b4da308f>", line 1, in <module>
ins1.foo
AttributeError: Test1 instance has no attribute 'foo'
>>> ins1.display(12)
foo : 12
>>> ins1.foo
12
就个人而言,我不喜欢在方法内部定义实例变量,除了
\uuuu init\uuuu
或者在上面的示例中定义为类变量,如bar
同样,就我个人而言,我喜欢通过看顶端来看到我班上的每个成员。无论是用作实例变量的类变量(我通常不这么做)还是在\uuuu init\uuuu
中定义的实例变量,通过检查类定义的第一部分,可以很容易地判断类中定义了什么和没有定义什么
如果您不需要以类成员的身份访问变量(即,您在那里定义它只是为了避免在\uuuu init\uuuu
方法中写入self.variable=val
),那么我会避开它。如果您可能需要以类变量的身份访问它,那么在我的书中使用bar
可以
这将是我写你们课的首选方式
class Test1:
def __init__(self):
self.foo = None
self.bar = 10
def display(self,foo):
self.foo=foo
print "foo : ",self.foo #80
def display1(self):
print "bar: ", self.bar #10
print "again foo: ", self.foo #80
bar
是一个类属性。由于Python中的类是对象,它们也可以有属性。bar
恰好位于该Test
对象上,而不是其实例
由于Python解析属性查找的方式,它看起来像是test1
有一个bar
属性,但它没有
另一方面,foo
在调用display(80)
后位于实例test1
上。这意味着Test
的不同实例在各自的foo
属性中可以有不同的值
当然,您可以使用类变量作为某种“共享默认值”,然后可以使用实例属性“覆盖”,但这可能会让人困惑
第二个问题
def display(self,foo):
self.foo=foo
foo = foo
print "self.foo : ",self.foo
print "foo : ",foo
让我们先来了解一下细节:self
不是一个关键字,它只是将第一个参数称为“self”的惯例,如果您愿意,您也可以将其称为“this”或“that”或“bar”,但我不推荐这样做
Python将传递对象,该对象上的方法作为第一个参数被调用
def display(self,foo):
此foo是display实例函数的第一个参数的名称
self.foo=foo
这会将名为“foo”的实例属性设置为作为第一个参数传递的值,您在该实例上调用了display()
。使用示例test1.display(80)
,self
将是test1
,foo
是80
和test1。foo
将因此设置为80
foo = foo
这根本不起作用。它引用第一个参数foo
接下来的两行再次引用实例变量
foo
,第一个参数foo
否,bar
不是实例变量。这两行非常不同,这就是为什么它不是关于“良好实践”的原因。这是关于什么适合您的情况,因为它们有不同的用途。另外,self.bar
工作是因为名称bar
首先在实例的命名空间中搜索,然后在类中搜索。self.bar
工作的事实并不总是意味着bar
是一个实例变量。我认为主要区别在于类属性是“共享的”,而不是它对所有实例都可用。
foo = foo