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?
答案 0 :(得分:2)
在Python2中,
class F(object)
将F
声明为new-style class(与经典类相对)。
在Python3中,所有类都是新式的,因此object
可以在那里省略。
某些Python功能(例如properties和super)仅适用于新式类。新式类还具有某些属性和方法,如mro
,这是经典类缺乏的。
经典类仅用于向后兼容。您定义的所有类都应该是新式类。
class G(F):
使G
成为F
的子类,而
H = F(1,2,3)
使H
成为F
的实例。
请注意,PEP8 Style Guide建议使用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})
答案 1 :(得分:1)
首先,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中不是必需的。)
您应该考虑阅读官方教程中的Classes部分或更适合新手的教程。正如millimoose所说,所有这些都将在任何值得其带宽的教程中涵盖。