python元类


类(object)

__new__生成一个对象self__init__则对这个对象self进行加工,即初始化操作。

__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object__new__()出来的实例返回。

__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()__new__()的基础上可以完成一些其它初始化的动作,__init__()不需要返回值。

__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用,即使是父类的实例也不行。

class MyClass:
    def __new__(cls):
        print("Creating instance")
        instance = super(MyClass, cls).__new__(cls)
        return instance

    def __init__(self, value):
        self.my_attribute = value
        print("Initializing instance")

    def my_method(self):
        return self.my_attribute

# 一旦类定义完成,你就可以使用`class`关键字后跟类名和一对圆括号来创建类的实例。这个过程称为实例化。
# 在这个例子中,`MyClass`被实例化为`my_instance`,同时传递了参数`10`给构造方法`__init__`。
my_instance = MyClass(10)

# 当调用my_instance.my_method()时,self指向my_instance
result = my_instance.my_method()

# 输出
# Creating instance
# Initializing instance

元类(Metaclass)

在面向对象编程的世界里,对象的创建和管理是构建复杂系统的基础。 类本身也是对象,它们是由一种特殊的对象【元类(Metaclass】所创建和管理的。

元类是面向对象语言中的一个高级概念,它不仅是类的模板,更是类的构造者。 在Python等动态语言中,元类扮演着至关重要的角色,它们定义了类的行为和创建过程。

Python中,元类(Metaclass)是创建类的“类”,它们定义了如何创建类和如何构造实例。简而言之,如果你把普通的类比作制造对象的模板,那么元类就是制造这些模板的模板。

所有的类都继承自object,而object是由type创建的。typePython中所有新式的元类,它提供了类创建的标准行为。在Python 3中,所有的类都是新式的,而Python 2中的类默认是旧式的,但可以通过继承object来变成新式的。

type本身也是一个类,由type的元类创建。这种递归的特性使得Python中的一切都是对象,包括类本身。

元类工作原理

type也是一个内置的工厂函数,可以用来创建新的类。

# 用type动态创建类
MyClass = type('MyClass', (BaseClass,), {'attribute1': value1, 'method1': function1})

自定义元类型

要涉及继承自type并重写其__new__或者__init__方法来控制如何创建或初始化新型态(即新建立一个class

# 定义一个名为 Meta 的元素, 继承自 type
# 这是一个类的类。
class Meta(type):
    def __new__(cls, name, bases, dct):
        print('__new__方法,创建一个类!不是实例!类名:', name)
        # 在类定义中添加一个新方法
        dct['new_method'] = lambda self: 'Hello from metaclass'
        return super(Meta, cls).__new__(cls, name, bases, dct)

    def __init__(cls, name, bases, dct):
        # dct['new_method'] = lambda self: 'Hello from metaclass'
        print('__init__方法,创建一个类!不是实例!类名:', name)
        super().__init__(name, bases, dct)


# 使用 Meta 元素来定制 MyClass 类型
class MyClass(metaclass=Meta):
    pass


# 实例化 MyClass 将会触发 Meta 的 __new__
obj = MyClass()
print(obj.new_method())

# 输出:
# __new__方法,创建一个类!不是实例!类名: MyClass
# __init__方法,创建一个类!不是实例!类名: MyClass
# Hello from metaclass

在上面代码中:

  • 1.首先声明了一个名为Meta的新型态,并且继承了内置型态type
  • 2.然后重写了该型态(Meta) 的构造方法(__new__)。
  • 3.当声明另外一种名为MyClass, 并指定其使用metaclass=Meta, Python将会在创建该MyClass时调用到由Meta提供的构造方法。

dct['new_method'] = lambda...__init__方法中不起作用,原因如下:

  • 1.执行时机不同:元类的__init__方法是在类对象已经被创建之后调用的。此时对传入参数dct的修改并不会影响到已经完成构造过程的类对象。换句话说,在通过元类型(Meta)构造完一个新类型(MyClass)之后再去尝试添加或修改属性、方法等内容,并不能改变已经生成好了结构和内容定义的那个类型。
  • 2.参数差异:虽然既__new____init__都接收到了名为dct的字典参数,但只有在new()中对dct执行操作才能影响到最终生成的类型结构。当执行到init()时候, 类型已经被成功创建, 此刻dct参数更多地扮演着提供信息参考角色,并不能通过修改它来改变现有类型结构。

元类的作用

元类可以用来控制类的创建过程。你可以使用元类来修改类的定义,或者在类创建时添加额外的行为。以下是一些元类可能的应用场景:

  • 1.注册机制:自动将类注册到某个字典或列表中,以便于查找或管理。
  • 2.单例模式:确保一个类只有一个实例。
  • 3.属性和方法的添加:在不修改类定义的情况下,为其添加额外的属性或方法。
  • 4.子类检查:检查一个类是否是另一个类的子类。
  • 5.自定义类的行为:修改类的创建过程,以实现自定义的行为。

旧式类(Old-style classes)

在Python 2中,如果你定义一个类没有明确指定基类,那么它就是旧式类。

新式类(New-style classes)

新式类的主要特点包括:

  • 1.更灵活的属性管理:新式类使用__slots__属性来定义类级别的属性,这可以节省内存并防止不必要的属性添加。
  • 2.更好的描述符支持:新式类支持更多的描述符协议,这使得属性和方法的管理更加灵活。
  • 3.统一的基类:新式类提供了一个统一的基类object,这使得所有的类都有共同的祖先,简化了继承体系。

results matching ""

    No results matching ""