zoukankan      html  css  js  c++  java
  • 第八章python元类编程

    1.property动态属性

      一般对象中的属性使用单下划线或双下划线开头的都是伪私有类型,对于单下划线开头的属性(表示为protected类型)直接可以通过对象访问,而双下滑线开头的属性(表示private类型)必须使用对象.__类名__私有属性名即可访问

     1 class Test:
     2     def __init__(self):
     3         self.__t1 = "t1"
     4         self._t2 = "t2"
     5 
     6 
     7 test = Test()
     8 print(test._Test__t1, test._t2)  # t1 t2
     9 
    10 test._Test__t1 = "Test_t1"
    11 test._t2 = "Test_t2"
    12 print(test._Test__t1, test._t2)  # Test_t1 Test_t2

      大家应该遵守一个约定就是不要对伪私有类型进行赋值等操作,我们应该使用函数调用的方式,为了让程序更加优雅,我们有装饰器@property让函数变为对象的属性

    • @property:设置age为对象属性默认隐藏掉__age,并且设置age像普通属性一样,使用user.age来获得值
    • @age.setter:设置@property修饰过的属性的赋值操作像普通属性一样,使用user.age = 65来赋值
     1 class User:
     2     def __init__(self, name):
     3         self.name = name
     4         self.__age = 0
     5 
     6     # 一般的函数调用
     7     def get_age(self):
     8         return self.__age
     9 
    10     # __age的get方法
    11     @property
    12     def age(self):
    13         return self.__age
    14 
    15     # __age的set方法
    16     @age.setter
    17     def age(self, value):
    18         if value > 150 or value < 0:
    19             raise ValueError('invalid age')
    20         self.__age = value
    21 
    22 
    23 if __name__ == "__main__":
    24     user = User("user1")
    25     user.age = 35
    26     print(user.age)  # 35
    27 
    28     user._User__age = 65
    29     print(user._User__age, user.age)  # 65 65
    30     print(user.get_age())  # 65

    2.__getattr__、__getattribute__魔法函数

    • __getattribute__:当访问属性时,都会进入这个魔法函数
    • __getattr:当访问属性时,没有找到访问的属性则调用这个魔法函数
     1 class User:
     2     def __init__(self, info={}):
     3         self.info = info
     4 
     5     def __getattr__(self, item):
     6         return self.info[item]
     7 
     8     # def __getattribute__(self, item):
     9     #     return "getattribute"
    10 
    11 
    12 if __name__ == "__main__":
    13     user = User(info={"company_name": "imooc", "name": "bobby"})
    14     print(user.name)  # imooc

    3.属性描述符和属性查找过程

    1.什么是属性描述符
      实现了__get__、__set__、__delete__中的任意一个方法的类,称为属性描述符

    2.什么是数据描述符

      实现__get__、__set__两个方法的类

    3.什么是非数据描述符

      只实现__get__方法的类

    4.属性的查找

      如果test_user是User类的实例,test_user.age 等价与getattr(test_user,'age')

    执行test_user.age步骤:

    1. 调用__getattribute__
      1. 如果没有找到属性age,则__getattribute__抛出AttributeError再调用__getattr__
      2. 如果可以找到age,则调用__get__

    进入__getattribute__整体流程:

     1 import numbers
     2 
     3 
     4 class IntField:
     5     # 数据描述符
     6     def __get__(self, instance, owner):
     7         return self.value
     8 
     9     def __set__(self, instance, value):
    10         if not isinstance(value, numbers.Integral):
    11             raise ValueError("int value need")
    12         if value < 0:
    13             raise ValueError("positive value need")
    14         self.value = value
    15 
    16     def __delete__(self, instance):
    17         pass
    18 
    19 
    20 class NonDataIntField:
    21     # 非数据属性描述符
    22     def __get__(self, instance, owner):
    23         return self.value
    24 
    25 
    26 class User:
    27     age = IntField()
    28     # age = NonDataIntField()
    29 
    30 
    31 if __name__ == "__main__":
    32     test_user = User()
    33     test_user.age = 1
    34     print(test_user.__dict__, User.__dict__)
    35     print(test_user.age)
    36     pass
    37     pass
    38     # print(dir(test_user))
    39     # print(test_user.age)

    4.__new__和__init__的区别

    5.自定义元类

    6.元类实现简单的orm

  • 相关阅读:
    tensorflow2知识总结---3、逻辑回归与交叉熵
    tensorflow2知识总结---2、多层感知器实例
    日常英语---200720(感知器:perceptron)
    日常英语---200720(numpy怎么读)
    日常英语---200720(tensorflow2优化函数:model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['acc']))
    tensorflow2知识总结---1、线性回归实例
    Guid.ToString Method
    Intercept HTTP requests
    Fetch API
    古墓惊魂 关卡奖励的宝藏
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/12094471.html
Copyright © 2011-2022 走看看