python是一種動態編程語言,能夠動態爲類和實例添加屬性.python
定義類:編程
class Dog: pass
定義一個方法:api
def get_name(self): return self.__name
給類動態添加屬性和方法:編程語言
Dog.__name = 'tiger' Dog.get_name = get_name
#調用 dog = Dog() print(dog.get_name())
輸出:
tiger函數
給實例添加屬性和方法:spa
from types import MethodType dog = Dog() dog.__name = 'tiger' dog.get_name = MethodType(get_name, dog) print(dog.get_name())
輸出:對象
tigerblog
示例:繼承
class Dog: __slots__ = ('get_name', 'name') def get_name(self): return self.name
僅容許爲Dog類和實例動態添加get_name和name屬性,添加其餘屬性引起AttributeError錯誤get
dog = Dog() dog.name = 'tiger' dog.age = 10 dog.get_name = MethodType(get_name, dog) print(dog.get_name())
輸出:
AttributeError: 'Dog' object has no attribute 'name'
注意:__slots__不會對繼承不起做用,僅對當前類和示例起做用.
Python內置的@property裝飾器就是負責把一個方法變成屬性調用
示例:
class Dog: def __init__(self): self.__age = 0 @property def age(self): return self.__age @age.setter def age(self, val): self.__age = val dog = Dog() dog.age = 10 print(dog.age)
python爲類提供了一些內置屬性,能夠方便的對類進行定製
__str__:是打印示例輸出的內容
__repr__:是在交互命令下輸出的實例內容
示例:
class Dog: def __str__(self): return 'class Dog' # 直接將__str__屬性複製給__repr__ __repr__ = __str__ dog = Dog() print(dog)
讓類能夠被迭代
示例代碼:
class Dog: def __init__(self): self.__max = 10 self.__index = 0 def __iter__(self): return self def __next__(self): if self.__index > 10: raise StopIteration() tmp = self.__index self.__index += 1 return tmp dogs = Dog() for dog in dogs: print(dog)
輸出:
0 1 2 3 4 5 6 7 8 9 10
讓類能夠像list同樣取下標和切片
取下標示例代碼:
class Dog: def __init__(self): self.__list = range(10) def __getitem__(self, index): if index >= len(self.__list): raise IndexError() return self.__list[index] dogs = Dog() print(dogs[1])
輸出:
1
既能夠取下標又能夠切片示例代碼:
class Dog: def __init__(self): self.__list = range(10) def __getitem__(self, index): if isinstance(index, int): if index >= len(self.__list): raise IndexError() return self.__list[index] if isinstance(index, slice): return list(self.__list)[index.start:index.stop] dogs = Dog() print(dogs[1:5])
輸出:
[1, 2, 3, 4]
__getattr__:但讀取屬性時,若是不存在則調用
__setattr__:但設置屬性時,若是不存在則調用
示例代碼:
class Dog(dict): def __init__(self): self.__name = 'dog' def __getattr__(self, item): return self[item] def __setattr__(self, key, value): self[key] = value dog = Dog() dog.age = 10 dog.sex = 1 print(dog.age, dog.sex)
REST API路徑示例:
class Chain: def __init__(self, path=''): self.__path = path def __getattr__(self, item): return Chain('%s/%s' % (self.__path, item)) def __str__(self): return self.__path path = Chain().v1.api.status print(path)
輸出:
/v1/api/status
將實例做爲函數調用
callable能夠判斷對象是否能夠做爲函數調用
示例代碼:
class Dog: def __call__(self, name): print('dog是一條狗,from-%s' % name) dog = Dog() if callable(dog): dog('dahuang') else: print('not call')