生活随笔
收集整理的這篇文章主要介紹了
Python的元类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、用元類驗證子類
每當我們定義新類的時候,元類就會運行雅正代碼,以確保這個新類符合規定的規范。
Python系統把子類的class語句處理完畢,就會調用元類的 __new__ 方法。元類可以通過 __new__ 方法,獲取子類、孫子類的名稱,父親及屬性。
這樣使得我們不需要將驗證代碼放在本類 __init__ 方法中,等到構建對象再驗證。
下例中,定義一個邊數小于3的子類,class語句一結束,元類的驗證代碼就會拒絕這個class。
class ValidatePolygon(type):def __new__(meta, name, bases, class_dict):# Don't validate the abstract Polygon classif bases != (object,):if class_dict['sides'] < 3:raise ValueError('Polygons need 3+ sides')return type.__new__(meta, name, bases, class_dict)class Polygon(object, metaclass=ValidatePolygon):sides = None # Specified by subclasses@classmethoddef interior_angles(cls):return (cls.sides - 2) * 180class Triangle(Polygon):sides = 3print(Triangle.interior_angles())
2、用元類注冊子類
每次從基類中繼承子類時,基類的元類都可以自動運行注冊代碼。
這在需要反向查找 ‘reverse lookup’ 時很有用,使得在簡單標識符和對應的類之間,建立映射關系。
依然利用的是class語句執行完,自動調用元類的 __new__ 方法。
import json registry = {}def register_class(target_class):registry[target_class.__name__] = target_classdef deserialize(data):params = json.loads(data)name = params['class']target_class = registry[name]return target_class(*params['args'])class Meta(type):def __new__(meta, name, bases, class_dict):cls = type.__new__(meta, name, bases, class_dict)register_class(cls)return clsclass Serializable(object):def __init__(self, *args):self.args = argsdef serialize(self):return json.dumps({'class': self.__class__.__name__,'args': self.args,})def __repr__(self):return '%s(%s)' % (self.__class__.__name__,', '.join(str(x) for x in self.args))class RegisteredSerializable(Serializable, metaclass=Meta):passclass Vector3D(RegisteredSerializable):def __init__(self, x, y, z):super().__init__(x, y, z)self.x, self.y, self.z = x, y, zv3 = Vector3D(10, -7, 3)
print('Before: ', v3)
data = v3.serialize()
print('Serialized:', data)
print('After: ', deserialize(data))print(registry)
3、用元類注解類的屬性
使用元類像是在 class 語句上放置了掛鉤,class語句處理完畢,掛鉤就會立刻觸發。
下列中借助元類設置了 Filed.name 和 Filed.name。
class Field(object):def __init__(self):# These will be assigned by the metaclass.self.name = Noneself.internal_name = Nonedef __get__(self, instance, instance_type):if instance is None: return selfreturn getattr(instance, self.internal_name, '')def __set__(self, instance, value):setattr(instance, self.internal_name, value)class Meta(type):def __new__(meta, name, bases, class_dict):for key, value in class_dict.items():if isinstance(value, Field):value.name = keyvalue.internal_name = '_' + keycls = type.__new__(meta, name, bases, class_dict)return clsclass DatabaseRow(object, metaclass=Meta):passclass BetterCustomer(DatabaseRow):first_name = Field()last_name = Field()prefix = Field()suffix = Field()foo = BetterCustomer()
print('Before:', repr(foo.first_name), foo.__dict__)
foo.first_name = 'Euler'
print('After: ', repr(foo.first_name), foo.__dict__)
元類總結就到這里,自己也沒有完全理解清楚。
希望對此有深刻理解的pythoner留言。
代碼來自:https://github.com/bslatkin/effectivepython
轉載于:https://www.cnblogs.com/lidyan/p/7157227.html
總結
以上是生活随笔為你收集整理的Python的元类的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。