面向對象

一.python面向對象之__slots__

1.爲對象和實例添加屬性/方法:

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

 

2.若是要限制添加的屬性怎麼辦?使用__slots__

示例:繼承

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

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爲類提供了一些內置屬性,能夠方便的對類進行定製

1.__str__和__repr__:

__str__:是打印示例輸出的內容
__repr__:是在交互命令下輸出的實例內容

示例:

class Dog:
    def __str__(self):
        return 'class Dog'
    
    # 直接將__str__屬性複製給__repr__
    __repr__ = __str__

dog = Dog()
print(dog)

  

2.__iter__和__next__:

讓類能夠被迭代

示例代碼:

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

  

3.__getitem__:

讓類能夠像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]

4.__getattr__和__setattr__:

__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

5.__call__

將實例做爲函數調用
callable能夠判斷對象是否能夠做爲函數調用

示例代碼:

class Dog:
    def __call__(self, name):
        print('dog是一條狗,from-%s' % name)

dog = Dog()
if callable(dog):
    dog('dahuang')
else:
    print('not call')
相關文章
相關標籤/搜索