2.4.5 对象的创建和类的创建

本节目标:

  • 了解通过一个类创建对象的过程

  • 了解类创建的过程

__init__方法中,我们已经可以使用self了,也就是说,__init__的调用发生在对象创建之后。 但在Python中,我们有办法干预到对象创建本身。

Learning By Reading 难度:★★ 重要性:★★★★★

同时,类也是对象,因此我们也有办法创建类对象。

Learning By Reading 难度:★★ 重要性:★★★

类也是对象,是一个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