zoukankan      html  css  js  c++  java
  • 元类编程--__get__ __set__属性描述符

    from datetime import date, datetime
    import numbers
    
    class IntField:
        #数据描述符,实现以下任意一个,都会变为属性描述符
        def __get__(self, instance, owner):
            return self.value
        def __set__(self, instance, value): #判断类型
            if not isinstance(value, numbers.Integral):
                raise ValueError("int value need")
            if value < 0:
                raise ValueError("positive value need")
            self.value = value
        def __delete__(self, instance):
            pass
    
    
    class NonDataIntField:
        #非数据属性描述符
        def __get__(self, instance, owner):
            return self.value
    
    class User:
        age = IntField()
        # age = NonDataIntField()
    
    '''
    如果user是某个类的实例,那么user.age(以及等价的getattr(user,’age’))
    首先调用__getattribute__。如果类定义了__getattr__方法,
    那么在__getattribute__抛出 AttributeError 的时候就会调用到__getattr__,
    而对于描述符(__get__)的调用,则是发生在__getattribute__内部的。
    user = User(), 那么user.age 顺序如下:
    
    (1)如果“age”是出现在User或其基类的__dict__中, 且age是data descriptor, 那么调用其__get__方法, 否则
    
    (2)如果“age”出现在user的__dict__中, 那么直接返回 obj.__dict__[‘age’], 否则
    
    (3)如果“age”出现在User或其基类的__dict__中
    
    (3.1)如果age是non-data descriptor,那么调用其__get__方法, 否则
    
    (3.2)返回 __dict__[‘age’]
    
    (4)如果User有__getattr__方法,调用__getattr__方法,否则
    
    (5)抛出AttributeError
    
    '''
    
    # class User:
    #
    #     def __init__(self, name, email, birthday):
    #         self.name = name
    #         self.email = email
    #         self.birthday = birthday
    #         self._age = 0
    #
    #     # def get_age(self):
    #     #     return datetime.now().year - self.birthday.year
    #
    #     @property
    #     def age(self):
    #         return datetime.now().year - self.birthday.year
    #
    #     @age.setter
    #     def age(self, value):
    #         #检查是否是字符串类型
    #         self._age = value
    
    if __name__ == "__main__":
        user = User()
        user.__dict__["age"] = "abc"
        print (user.__dict__)
        print (user.age)
        # print (getattr(user, 'age'))
        # user = User("bobby", date(year=1987, month=1, day=1))
        # user.age = 30
        # print (user._age)
        # print(user.age)
  • 相关阅读:
    楼市十大卖楼花招曝光〔转载〕
    Redhat中通过命令工具和配置文件设置TCP/IP参数的方法
    远程桌面超大最大连接数,无法连接服务器解决办法[转载]
    七夕祝福
    决定成败的人生细节
    QTP总结〔转载〕
    如何理解Return的返回值?
    IT人士群聚喝酒的讲究(转载)
    20 个增强表单功能的 jQuery 插件
    Windows Phone灵魂诠释:Metro UI界面完全解析
  • 原文地址:https://www.cnblogs.com/Erick-L/p/8876916.html
Copyright © 2011-2022 走看看