python类定义关键字参数_python – 为什么类定义的metaclass关键字参数接受可调用?...

关于你的第一个问题,元类应该是MyMetaclass(就是这样):

In [7]: print(type(MyClass), type(MyDerived))

原因是,如果元类不是python类型的实例,则通过将这些参数传递给它来调用methaclass name,bases,ns,** kwds(请参阅new_class)并且因为你在该函数中返回真正的元类,它会得到元类的正确类型.

关于第二个问题:

What is the purpose of accepting an arbitrary callable?

没有特殊目的,它实际上是元类的本质,因为从类中创建实例总是通过调用它的__call__方法来调用元类:

Metaclass.__call__()

这意味着你可以传递任何可调用的元类作为你的元类.因此,例如,如果使用嵌套函数对其进行测试,结果仍将是相同的:

In [21]: def metaclass_callable(name, bases, namespace):

def inner():

return MyMetaclass(name, bases, namespace)

return inner()

....:

In [22]: class MyClass(metaclass=metaclass_callable):

pass

....:

In [23]: print(type(MyClass), type(MyDerived))

有关更多信息,请参阅Python如何创建类:

它调用new_class函数,它在其自身内部调用prepare_class,然后你可以在prepare_class中看到python调用相应元类的__prepare__方法,除了找到正确的元(使用_calculate_meta函数)并为类创建适当的命名空间.

所以这里所有的都是执行metacalss方法的层次结构:

> __prepare__ 1

> __call__

> __new__

> __init__

这是源代码:

# Provide a PEP 3115 compliant mechanism for class creation

def new_class(name, bases=(), kwds=None, exec_body=None):

"""Create a class object dynamically using the appropriate metaclass."""

meta, ns, kwds = prepare_class(name, bases, kwds)

if exec_body is not None:

exec_body(ns)

return meta(name, bases, ns, **kwds)

def prepare_class(name, bases=(), kwds=None):

"""Call the __prepare__ method of the appropriate metaclass.

Returns (metaclass, namespace, kwds) as a 3-tuple

*metaclass* is the appropriate metaclass

*namespace* is the prepared class namespace

*kwds* is an updated copy of the passed in kwds argument with any

'metaclass' entry removed. If no kwds argument is passed in, this will

be an empty dict.

"""

if kwds is None:

kwds = {}

else:

kwds = dict(kwds) # Don't alter the provided mapping

if 'metaclass' in kwds:

meta = kwds.pop('metaclass')

else:

if bases:

meta = type(bases[0])

else:

meta = type

if isinstance(meta, type):

# when meta is a type, we first determine the most-derived metaclass

# instead of invoking the initial candidate directly

meta = _calculate_meta(meta, bases)

if hasattr(meta, '__prepare__'):

ns = meta.__prepare__(name, bases, **kwds)

else:

ns = {}

return meta, ns, kwds

def _calculate_meta(meta, bases):

"""Calculate the most derived metaclass."""

winner = meta

for base in bases:

base_meta = type(base)

if issubclass(winner, base_meta):

continue

if issubclass(base_meta, winner):

winner = base_meta

continue

# else:

raise TypeError("metaclass conflict: "

"the metaclass of a derived class "

"must be a (non-strict) subclass "

"of the metaclasses of all its bases")

return winner

1.请注意,它会在new_class函数内部和返回之前隐式调用.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值