对于一次考试,教授要求我编写一个对项目中的所有类都有效的元类,而不必直接在类声明中声明它,这可能吗?如何?例如我有以下代码:
class MetaOne(type):
def __new__(meta, classname, supers, classdict):
print('In MetaOne.new: ', classname, supers, classdict, sep='\n...')
return type.__new__(meta, classname, supers, classdict)
def __init__(Class, classname, supers, classdict):
print('In MetaOne init:', classname, supers, classdict, sep='\n...')
print('...init class object:', list(Class.__dict__.keys()))
class Eggs: pass
print('making class')
class Spam(Eggs):
data = 1
def meth(self, arg): pass
print('making instance')
X = Spam()
print('data:', X.data)
我希望输出等于以下代码的输出:
class MetaOne(type):
def __new__(meta, classname, supers, classdict):
print('In MetaOne.new: ', classname, supers, classdict, sep='\n...')
return type.__new__(meta, classname, supers, classdict)
def __init__(Class, classname, supers, classdict):
print('In MetaOne init:', classname, supers, classdict, sep='\n...')
print('...init class object:', list(Class.__dict__.keys()))
class Eggs: pass
print('making class')
class Spam(Eggs, metaclass=MetaOne):
data = 1
def meth(self, arg): pass
print('making instance')
X = Spam()
print('data:', X.data)
即使我没有直接声明它,元类也将应用于我的所有类。我对元类有很多疑问,但是最后在定义类时,总是使用metaclass = meta声明。
好吧,我很难理解您的问题。
如果Eggs
继承MetaOne
并Spam
继承Eggs
,这是否完成了您要尝试执行的操作?
class MetaOne(metaclass=ABCMeta):
pass
class Eggs(MetaOne):
pass
class Spam(Eggs):
pass
也许lgiordani.com上的可用信息对您有用,尤其是前一链接中的以下代码块:
class FilterClass(type):
@classmethod
def __prepare__(name, bases, **kwds):
return collections.OrderedDict()
def __new__(metacls, name, bases, namespace, **kwds):
result = type.__new__(metacls, name, bases, dict(namespace))
result._filters = [
value for value in namespace.values() if hasattr(value, '_filter')]
return result
此代码块演示了如何在不使用的情况下创建元类metaclass=ABCMeta
。
你熟悉super()
吗?
class MetaOne:
def __init__(self, name):
self.name = name
class Eggs: pass
class Spam(MetaOne, Eggs):
def __init__(self, name, is_tasty):
super().__init__(name)
self.is_tasty = is_tasty
>>> s = Spam('meta', True)
>>> s
<__main__.Spam object at 0x100705b38>
>>> s.name
'meta'
>>> s.is_tasty
True
虽然使用super()
不是真正的元类
根据您的Python版本,您也许可以__metaclass__ = MetaOne
在模块级别进行定义,这将影响该声明下的所有类。
class MetaOne: pass
class Eggs: pass
__metaclass__ = MetaOne
class Spam: pass
class Scrambled: pass
class Fried: pass
在此用例中Spam
,Scrambled
和的元类Fried
将全部是MetaOne
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句