我已经看到了如何在类中创建静态变量的示例。这是一个示例:
class A:
_i = 0
@property
def i(self):
print(type(self)) # <class '__main__.A'>
return type(self)._i
@i.setter
def i(self, val):
type(self)._i = val
type(self)
如何工作并使这些变量变为静态? < class '__main__.A' >
在OOP和多态性中意味着什么?答案 0 :(得分:4)
类型(自身)如何工作
它仅返回self
的类型。您可以在任何对象上调用type
以获取其类型:
>>> type(2)
int
>>> class C(object): pass
>>> type(C)
type
>>> c = C()
>>> type(c)
__main__.C
(在Python 2与Python 3或不同的Python实现上,输出看起来可能略有不同。)
…并使变量为静态变量?
首先,这些不是静态变量,它们是类变量。如果您没有任何继承,就没有区别,但是如果您有…,我会再说一遍。
如果您创建实例:
>>> a = A()
…并为i
分配一个值:
>>> a.i = 3
…它调用i
属性的setter,将a
作为self
参数传递,就像普通的方法调用一样。
因此,由于self
是a
,而type(a)
是A
,所以type(self)
也是A
。
这意味着type(self)._i
是A._i
。换句话说,它是class属性。
那么,为什么这是类属性而不是静态属性?好吧,让我们添加一个子类:
>>> a = A()
>>> class B(A):
... _i = 1
>>> b = B()
>>> b.i = 5
>>> A._i
0
>>> B._i
5
每个子类可以有自己的_i
。并且由于设置程序正在设置type(self)._i
,因此当self
为b
时,type(self)
为B
,type(self)._i
为B._i
,不是A._i
。
< class '__main__.A' >
在OOP和多态性中是什么意思
在Python中,所有内容都有一个repr
,供程序员使用,当您在交互式提示符下对其进行评估时,该文件将被打印出来。如果没有更好的人类可读的表示形式(如在真实的人类中,而不是在我们的程序员中),它也可用作str
(由print
打印的东西)。
通常,repr
是:
<>
中的字符串,其中包括类型,某种识别信息(如果有的话)以及某种将对象与其他实例区分开的方法。对于类型,您会在尖括号内得到的事实是它是一个类(即class
部分)和限定名称(即__main__.A
部分,告诉您这是一个类别在名为A
的模块的顶层定义的名为__main__
的类,这既是有用的标识符,也是将其与其他类区分开的方式。
什么是OOP和多态性?我想不到一个好的答案。即使Python不支持多态,即使没有一流的类型,__main__.A
和__main__.B
仍然是值得不同名称的不同对象,对吗?
如果您想知道__main__
是什么类型,那只是用于运行顶级脚本或交互式解释器会话的特殊模块的名称。如果您曾经见过if __name__ == '__main__':
守卫,那就是它正在测试的内容。
答案 1 :(得分:1)
type()
返回构造实例的class
。即如果您执行foo = A()
(创建A
的新实例并将其分配给foo
),则type(foo)
会再次返回A
。这就是<class '__main__.A'>
,它告诉您它是A
class
对象。
现在,您对type(self)._i
所做的一切与A._i
相同。 _i
是class
A
对象的属性,该对象仅存在一次。等等,这就是所有“静态”属性。