2.4.5 对象的创建和类的创建
本节目标:
了解通过一个类创建对象的过程
了解类创建的过程
在__init__方法中,我们已经可以使用self了,也就是说,__init__的调用发生在对象创建之后。 但在Python中,我们有办法干预到对象创建本身。
Learning By Reading 难度:★★ 重要性:★★★★★
阅读材料,了解
__new__。
同时,类也是对象,因此我们也有办法创建类对象。
Learning By Reading 难度:★★ 重要性:★★★
阅读材料,了解metaclass(元类)。
类也是对象,是一个type类型的对象,所以我们看到在创建类的时候我们用到了type类的__new__方法。 这一点,类和其他对象没有区别。
我们先来玩一玩__new__~
class MyTurtle(turtle.Turtle):
_all_turtles = {}
def __init__(self, name, *args, **kwargs):
self.name = name
MyTurtle._all_turtles[name] = self
@classmethod
def get_by_name(cls, name):
return cls._all_turtles[name]
ada = MyTurtle('ada')
if MyTurtle.get_by_name('ada') == ada:
print("找到了ada") # 输出
ada2 = MyTurtle('ada')
if MyTurtle.get_by_name('ada') == ada2:
print("又找到了ada") # 输出
if ada == ada2:
print("两只一样的ada") # 不输出大家想一下就发现,ada = MyTurtle('ada')和ada2 = MyTurtle('ada')虽然都是创建了名字是ada的小海龟, 但是只是名字相同,并不是真的是同一只。并且后一只会在MyTurtle._all_turtles里面覆盖掉前面一只。
如果想要让每次MyTurtle('ada')的时候都得到同一只小海龟应该怎么做呢?
class MyTurtle(turtle.Turtle):
_all_turtles = {}
def __new__(cls, name, *args, **kwargs):
if name not in cls._all_turtles:
cls._all_turtles[name] = super(MyTurtle).__new__(*args, **kwargs)
return cls._all_turtles[name]
def __init__(self, name):
self.name = name
ada = MyTurtle('ada')
ada2 = MyTurtle('ada')
if ada == ada2:
print("两只一样的ada") # 输出__new__告诉Python如何创建MyTurtle类的对象, ada = MyTurtle('ada')的时候,Python发现ada这个名字不在MyTurtle._all_turtles里面,于是返回了一个新创建的海龟对象(用super(MyTurtle).__new__)。 ada2 = MyTurtle('ada')的时候,就直接返回储存在MyTurtle._all_turtles中的ada了。
我们之前介绍过,Python中的类也是对象,每个类都是type对象。 type类就是用来创建类对象的,也是通过__new__方法。
class MyTurtle(turtle.Turtle, AnotherClass, AnotherAnotherClass):
_all_turtles = {}
def __init__(self, name):
self.name = name这样定义一个类,等价于
def __init__(self, name):
self.name = name
MyTurtle = type('MyTurtle', (turtle.Turtle, AnotherClass, AnotherAnotherClass), {'_all_turtles': {}, '__init__': __init__})后一种方法直接用type类生成了一个类。 我们看到type带了三个参数,第一个是一个字符串表示类名,第二个是一个tuple表示继承哪些类,第三个是一个字典表示所有的属性和方法。
Last updated