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)
  • 相关阅读:
    Python3入门基础--str常用方法
    大学jsp实验4include,forword
    大学jsp实验3include指令的使用
    初识MFC----运行时类信息机制
    状态栏
    工具栏
    菜单栏
    程序启动画面
    字符串的截取
    字符串相关类
  • 原文地址:https://www.cnblogs.com/Erick-L/p/8876916.html
Copyright © 2011-2022 走看看