研究了好几晚都搞不下来,网上所有资料都找遍了T_T
有劳各位bigmaster先看代码吧:
代码1:
class Tmeta(type):
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
def with_metaclass(meta, *bases):
class metaclass(meta):
def __new__(cls, name, bases, attrs):
print(cls, name, bases, attrs)
return meta(cls, name, bases, attrs)
return type.__new__(metaclsss, 'withmeta', (), {})
# 原版会传入一个object对应with_metaclass参数*bases,不过我发现传不传入都对这个问题不影响
class Textclass(with_metaclass(Tmeta)):
# 随便设一些属性,和属性应该没关系
number = 666
def __init__(self, name):
self.name = name
def say(self):
print(f'my name is {self.name}')
t = Textclass('John')
t.say()
代码2:
class Tmeta(type):
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
class maclass(Tmeta):
def __new__(cls, name, bases, attrs):
print(cls, name, bases, attrs)
return Tmeta(cls, name, bases, attrs)
Withmeta = type.__new__(maclsss, 'withmeta', (), {})
class Textclass(Withmeta):
# 随便设一些属性,和属性应该没关系,试过textclass里面即使设成pass结果也是一样报错
number = 666
def __init__(self, name):
self.name = name
def say(self):
print(f'my name is {self.name}')
t = Textclass('John')
t.say()
代码3(以下主要都是对代码1和代码2自己用其他类似写法的测试):
class Tmeta(type):
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
class maclass(Tmeta):
def __new__(cls, name, bases, attrs):
print(cls, name, bases, attrs)
return Tmeta(cls, name, bases, attrs)
class Withmeta(metaclass=maclass)
pass
class Textclass(Withmeta):
number = 666
def __init__(self, name):
self.name = name
def say(self):
print(f'my name is {self.name}')
t = Textclass('John')
t.say()
代码4:
class Tmeta(type):
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
class maclass(Tmeta):
def __new__(cls, name, bases, attrs):
print(cls, name, bases, attrs)
return Tmeta(cls, name, bases, attrs)
class Textclass(metaclass=maclass):
number = 666
def __init__(self, name):
self.name = name
def say(self):
print(f'my name is {self.name}')
t = Textclass('John')
t.say()
1.为什么只有代码2会报错?这里主要是为了搞懂代码1和代码2之间的不同。据我所知这个with_metaclass()
相当于是个闭包,return type.__new__(metaclsss, 'withmeta', (), {})
是with_metaclass()
的返回主体,猜测with_metaclass()
传递完属性给Textclass
后type.__new__(metaclsss, 'withmeta', (), {})
就会消失,只在栈堆里保留这些属性作为freevars存在,也不知这个猜测是否正确。
2.如果把functionwith_metaclass()
拆开来写,实现与代码1最近似(最好是完全相同)的结果,应该怎么写?这个问题主要是想清楚理解到底这with_metaclass()
到底内部运作逻辑干了啥导致这样的结果以及彻底明白与代码2中的Withmeta
都有些啥不一样
3.type__new__(metaclass, name, bases, ns)
和metaclass(name, bases, ns)
除了调用的函数少了个__init__
之外有啥不一样?主要是想知道type.__new__
和type()
创建的class有什么不同。
我的brother告诉我,我爸爸是b,但原来a才是他爸爸,而a是b的爸爸。当我把我brother从历史中抹除,一切恢复正常(当然深入的问题还有其他副原因,但我懂了)