python 元类的call_Python元类中的__call__和__new__的区别?

我在这里再修改仔细说明下吧

元类是定义类结构属性的, 而类里的 "__new__", "__init__" 方法, 是处理类实例用的

我们所定义的每一个类, 都可以理解为是 type 的一个实例

class Foo(object):

version = "1.0.1"

pass

print(Foo.version) # 1.0.1

print(Foo.__name__) # Foo

# ------------

# 使用type创建类是一样的

Foo = type("Foo", (object,), dict(version="1.0.1"))

print(Foo.version) # 1.0.1

print(Foo.__name__) # Foo

好, 说回到 "__new__" 和 "__call__"

元类中, "__new__" 会在你定义类的时候执行, 只执行一次, 如果有两个类使用了这个元类, OK, 会执行两次

class FooMeta(type):

def __new__(meta, name, bases, dct):

print("metaclass __new__")

return type(name, bases, dct)

class Foo():

__metaclass__ = FooMeta

# 没有任何代码了, 你会看到 print了metaclass __new__

# 如果你细心, 并联系上面说的, 理解为

# Foo = type("Foo", tuple(), dict())

# 就明白 FooMeta.__new__原来就是 type.__new__

# Foo 是type的一个实例

# 这是为什么定义元类都要base type的原因: class FooMeta(type)

# 如果你定义 __metaclass__ = type 并没什么错, 因为本来默认就是这样

而__call__会在你每次实例化的时候调用, 其实和Foo.__new__是一样的, 意思是, 如果你的Foo定义了__new__, 元类中的__call__便不会执行

class FooMeta(type):

def __new__(meta, name, bases, dct):

print("metaclass __new__")

return type(name, bases, dct)

def __call__(self, *args, **kwargs):

print("meta __call__")

return "hello"

class Foo():

__metaclass__ = FooMeta

def __new__(cls, *args, **kwargs):

print("Foo __new__")

return "hello"

f = Foo()

print(f)

# 输出结果

# metaclass __new__

# Foo __new__

# hello

元类的 "__new__" 可以变更你所定义的类型, 我在这里定义Foo成了一个list

# -*- coding: utf-8 -*-

class FooMeta(type):

def __new__(cls, name, bases, dct):

return [1, 2, 3, 4]

# 这里相当于执行 Foo = [1, 2, 3, 4]

class Foo():

__metaclass__ = FooMeta

print(Foo) # [1, 2, 3, 4]

print(Foo[0:2]) # [1, 2]

print(Foo.pop()) # 4

写这么多很辛苦的, 能正解理解metaclass的人非常的少, 不知题主要怎么感谢我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值