
*****
### \_\_getattr\_\_和\_\_getattribute\_\_魔法函數
~~~
from datetime import date,datetime
class User:
def __init__(self,name,birthday):
self.name = name
self.birthday = birthday
def __getattr__(self,item):
print("not find attr")
def __getattribute__(self,item):
return "juran"
if __name__ == "__main__":
user = User("juran",date(year=1990,month=1,day=1))
print(user.age)
~~~
### 屬性描述符
~~~
class User:
def __init__(self,age):
self.age = age
def get_age(self):
return (str(self.age) + '歲')
def set_age(self,age):
if not isinstance(age,int):
raise TypeError('Type Error')
self.age = age
~~~
如果User類中有多個屬性都需要判斷,那么就需要寫多個方法,這些方法怎么復用呢?這個時候就要用到屬性描述符
~~~
屬性描述符,只要實現了__get__,__set__,__delete__任何一個方法,就被稱為屬性描述符
~~~
### 屬性查找順序
~~~
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
~~~
### 自定義元類
動態創建類
~~~
def create_class(name):
if name == "user":
class User:
def __str__(self):
return "user"
return User
elif name == "student":
class Student:
def __str__(self):
return "Student"
return Student
if __name__ == "__main__":
myclass = create_class('user')
obj = myclass()
print(obj)
print(type(obj))
~~~
### 使用type創建類
type還可以動態的創建類,type(類名,由父類組成的元組,包含屬性的字典)
* 第一個參數:name表示類名稱,字符串類型
* 第二個參數:bases表示繼承對象(父類),元組類型,單元素使用逗號
* 第三個參數:attr表示屬性,這里可以填寫類屬性、類方式、靜態方法,采用字典格式,key為屬性名,value為屬性值
### metaclass屬性
如果一個類中定義了metalass = xxx,Python就會用元類的方式來創建類