Python OOP-解释如何静态处理type(self)

时间:2018-08-21 06:46:49

标签: python python-3.x oop

我已经看到了如何在类中创建静态变量的示例。这是一个示例:

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和多态性中意味着什么?

2 个答案:

答案 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参数传递,就像普通的方法调用一样。

因此,由于selfa,而type(a)A,所以type(self)也是A

这意味着type(self)._iA._i。换句话说,它是class属性。


那么,为什么这是类属性而不是静态属性?好吧,让我们添加一个子类:

>>> a = A()
>>> class B(A):
...     _i = 1
>>> b = B()
>>> b.i = 5
>>> A._i
0
>>> B._i
5

每个子类可以有自己的_i。并且由于设置程序正在设置type(self)._i,因此当selfb时,type(self)Btype(self)._iB._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相同。 _iclass A对象的属性,该对象仅存在一次。等等,这就是所有“静态”属性。