python元类可以有方法吗?
是的,正如第一个示例所示,它们可以有方法,并且可以在实现元类的类上调用。
例如在python-3中。x元类
type
mro
>>> object.mro()
[object]
但您无法在实例上访问它们:
>>> object().mro()
AttributeError: 'object' object has no attribute 'mro'
但当我这么做的时候
dir(someClass)
这两种方法不显示。
dir
电话
type.__dir__
这只是展示了有限数量的方法:
方法之一:
>>> 'mro' in dir(object)
False
然而
目录
__dir__
在“实例的类”上调用,并且您的“元类是类的类型”,您必须在元类上实现它:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
def getInstance(cls):
print("Class is {}".format(cls.__name__))
if not cls in cls._instances:
raise LookupError("No instance of the class {cls} create yet.".format(cls.__name__))
return cls._instances[cls]
def clearInstance(cls):
cls._instances.pop(cls, None)
def __dir__(self):
normal_dir = type.__dir__(self)
# Also include all methods that don't start with an underscore and
# not "mro".
normal_dir.extend([
f for f in dir(type(self))
if not f.startswith('_')
and f != 'mro'
])
return normal_dir
class someClass(metaclass=Singleton):
def __init__(self,val):
self.value = val
>>> dir(someClass)
[..., 'clearInstance', 'getInstance']
现在,当您调用时,类的这些方法是可见的
.
向元类添加方法正确吗?
这取决于语境。我认为可以将这些方法添加到元类中。然而,这些应该很少使用。
classmethod
. 否则,它将显示正确的类。我不明白这种行为,有人能解释一下吗?
如果你仔细想想,这是显而易见的。
Singleton
是你的班级吗
someClass
当你成为一个
这个
cls
参数将为
独生子女
_instances
是
someClass类
cls公司
但这只是一个惯例,因为
self
是的实例的典型参数名称
class
cls公司
实例的典型参数名称
metaclass
metacls
. 还修复了
str.format
(这就是它抛出
KeyError
LookupError
):
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
print(cls._instances) # print the dict after creating an instance
return cls._instances[cls]
@classmethod
def getInstance(metacls):
print("Class is {}".format(metacls))
if not metacls in metacls._instances:
raise LookupError("No instance of the class {0} create yet.".format(metacls.__name__))
return metacls._instances[metacls]
@classmethod
def clearInstance(metacls):
metacls._instances.pop(metacls, None)
class someClass(metaclass=Singleton):
def __init__(self,val):
self.value = val
>>> sc = someClass(1)
{<class '__main__.someClass'>: <__main__.someClass object at 0x00000235844F8CF8>}
>>> someClass.getInstance()
Class is <class '__main__.Singleton'>
LookupError: No instance of the class Singleton create yet.
因此,您将“类”添加到dict中,然后检查元类是否在dict中(而不是)。
classmethods
(除了那些应该/可能是classmethods的方法,例如。
__prepare__