类和对象-type属性
本帖最后由 BrightXiong 于 2023-4-6 19:03 编辑>>> # 一、给所有的类添加一个属性:
>>> class MetaC(type):
... def __new__(mcls, name, bases, attrs):
... attrs['author'] = 'fishc'
... return type.__new__(mcls, name, bases, attrs)
...
>>> class C(metaclass=MetaC):
... pass
...
>>> class D(metaclass=MetaC):
... pass
...
>>> c = C()
>>> d = D()
>>> print(c.author, d.author)
fishc fishc
>>> class MetaC(type):
... def __init__(cls, name, bases, attrs):
... cls.author = 'fishc'
... return type.__init__(cls, name, bases, attrs)
...
>>> class C(metaclass=MetaC):
... pass
>>> class D(metaclass=MetaC):
... pass
...
>>> c = C()
>>> d = D()
>>> print(c.author, d.author)
fishc fishc
>>> # 二、对类名的定义规范做限制
>>> class MetaC(type):
... def __init__(cls, name, bases, attrs):
... if not name.istitle():
... raise TypeError('类名必须为大写字母开头!')
... type.__init__(cls, name, bases, attrs)
...
>>> try:
... class mycls(metaclass=MetaC):
... pass
... except TypeError as e:
... print(e)
...
类名必须为大写字母开头!
>>> # 三、修改对象的属性值 -> 如:把对象的所有字符串属性值都变成大写
>>> class MetaC(type):
... def __call__(cls, *args, **kwargs):
... new_args =
... return type.__call__(cls, *new_args, **kwargs)
...
>>> class C(metaclass=MetaC):
... def __init__(self, name):
... self.name = name
...
>>> c = C('FishC')
>>> print(c.name)
FISHC
>>> # 当然如果传入的不是str就不显示
>>> class C(metaclass=MetaC):
... def __init__(self, *name):
... self.name = name
...
>>> c = C('FishC', 'Python', 123)
>>> print(c.name)
('FISHC', 'PYTHON')
>>> # 四、限制类实例化时的传参方式 -> 如:要求类在实例化对象时只能关键字参数传参
>>> class MetaC(type):
... def __call__(cls, *args, **kwargs):
... if args:
... raise TypeError('仅支持关键字参数~~')
... return type.__call__(cls, *args, **kwargs)
...
>>> class C(metaclass=MetaC):
... def __init__(self, name):
... self.name = name
...
>>> try:
... c = C('fishc')
... except TypeError as e:
... print(e)
...
仅支持关键字参数~~
>>> c = C(name='fishc')
>>> print(c.name)
>>>fishc
>>> # 五、禁止一个类被实例化
>>> class NoInstances(type):
... def __call__(self, *args, **kwargs):
... raise TypeError('该类禁止实例化')
...
>>> class C(metaclass=NoInstances):
... pass
...
>>> try:
... c = C()
... except TypeError as e:
... print(e)
...
该类禁止实例化
>>> # 禁止实例化对象也可以使用静态方法和类方法
>>> class C(metaclass=NoInstances):
... @staticmethod
... def static_ok():
... print('静态方法允许使用~~')
... @classmethod
... def class_ok(cls):
... print('类方法也允许使用')
...
>>> C.static_ok()
静态方法允许使用~~
>>> C.class_ok()
类方法也允许使用
>>> # 六、只允许实例化一个对象
>>> class OnlyInstance(type):
... def __init__(cls, *args, **kwargs):
... cls.__instance = None
... type.__init__(cls, *args, **kwargs)
... def __call__(cls, *args, **kwargs):
... if cls.__instance is None:
... cls.__instance = type.__call__(cls, *args, **kwargs)
... return cls.__instance
... else:
... return cls.__instance
...
>>> class C(metaclass=OnlyInstance):
... pass
...
>>> c1 = C()
>>> c2 = C()
>>> print(c1 is c2)
True
>>> # c1和c2为同一个对象
>>> print(dir(C))
['_OnlyInstance__instance', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> # 对象被保存在类里边的_OnlyInstance__instance这个属性中
>>>
页:
[1]