class F(object): # is the word 'object' meaningful?
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
class G(F): # How does this subclass definition
a = 1
b = 2
c = 3
H = F(1,2,3) # differ from this one?
2 回答
在 Python2 中,
class F(object)
声明F
为新式类(相对于经典类)。在 Python3 中,所有的类都是新式的,所以这里object
可以省略。
某些 Python 功能,例如properties和super,仅适用于新式类。新式类也有某些属性和方法,比如mro
经典类所缺乏的。
经典类仅用于向后兼容。您定义的所有类都应该是新式类。
class G(F):
G
生成 的子类,F
而
H = F(1,2,3)
做H
一个. _ _F
请注意,PEP8 样式指南建议使用 CapWords 命名类,而为实例提供小写名称。(所以H
应该是h
......)
请务必注意类属性和实例属性之间的区别。定义
class F(object):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
给出F
实例属性的实例. 分配self.a = a
等仅在__init__
调用方法时执行,这发生在F
创建实例时。例如,当你说
H = F(1,2,3)
请注意,可以在以下位置检查这些实例属性H.__dict__
:
>>> H.__dict__
>>> {'a': 1, 'b': 2, 'c': 3}
他们不在F.__dict__
. _
>>> F.__dict__
>>> dict_proxy({'__dict__': <attribute '__dict__' of 'F' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'F' objects>, '__doc__': None, '__init__': <function __init__ at 0xae90ae4>})
键F.__dict__
是类属性。它们由 的所有实例共享F
。实例属性特定于每个实例,并且在实例之间可能不同。
请注意,由于H
是 的实例F
,H
因此可以访问F
的类属性以及它自己的实例属性。例如,
>>> H.__module__
>>> '__main__'
这就是基础知识,尽管关于 Python 属性查找规则还有很多内容可以说。有关这些规则的更完整描述,请参阅Chaturvedi。
现在当你说
class G(F):
a = 1
b = 2
c = 3
您正在定义a
,b
并c
成为 的类属性G
。请注意,可以在以下位置检查这些类属性G.__dict__
:
>>> G.__dict__
>>> dict_proxy({'a': 1, '__module__': '__main__', 'b': 2, 'c': 3, '__doc__': None})
首先,H
不是 的子类,F
而是 的实例。F
尝试打印出类型:
>>> type(G)
builtins.type
>>> type(H)
__main__.F
具体细节在不同的 Python 版本中可能会有所不同,但重点是它G
是一个类,一个类型的对象type
,而H
一个实例,一个类型的对象F
。
其次,G
设置名为、和的类属性。在任何类型的实例中,这些都将被同名的实例变量隐藏。但是您可以直接在课堂外访问它们。(如果你不了解类属性……你不想要它们。)a
b
c
G
同样,尝试将内容打印出来可能会有所帮助:
>>> G.a
1
>>> g = G(5, 6, 7)
>>> g.a
5
最后,对于您的附带问题:
“对象”这个词有意义吗?
是的。它是 Python 2.x 中所有新式类的基类名称。所以,做class F(object):
使你的班级成为一个新式的班级。(这在 Python 3.x 中不是必需的。)
您应该考虑阅读官方教程中的类部分,或者阅读对新手更友好的教程。正如 millimoose 所说,所有这些都将包含在任何值得其带宽的教程中。