python:面向對象程序設計進階(一):控制屬性的三種方式

一.@propertyhtml

在文章python

python:面向對象程序設計及property裝飾器

二.__slost__使用post

先定義簡單的一個類:url

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age

因爲Python是能夠動態綁定屬性和方法的,一次,能夠對一個雷或者類實例綁定一個屬性.若是對一個對象綁定一個屬性,該屬性支隊當前對象起做用,類的其餘對象是沒有這個屬性的,spa

如:設計

if __name__ == "__main__":
    stu1 = Student('alex',18)
    #對stu1對象綁定一個nickname屬性
    stu1.nickname = 'littel alex'
    stu2 = Student('lisi',16)
print(stu1.nickname) #'littel alex'
# stu2沒有nickname屬性,所以出現異常
#print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname'
print(stu1.nickname) #'littel alex'
print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname'

在建立類時(若是沒有使用__slots__屬性),python會爲每一個實例串講一個__dict__屬性,以字典的形式存放每一個實例的屬性,咱們分別打印stu1和sut2的__dict__屬性:code

print(stu1.__dict__)
print(stu2.__dict__)
'''
{'name': 'alex', 'age': 18, 'nickname': 'littel alex'}
{'name': 'lisi', 'age': 16}
'''

若是要對類的全部對象都綁定一個屬性,name就要綁定在類上:orm

Student.nickname = 'litter student'

這時stu1和stu2都具備nickname屬性了htm

若是進制對類進行屬性的添加和刪除,就要在定義類時定義一個特殊的__slots__屬性便可,這樣的類建立後將包含指定的元素,而沒有__dict__屬性,對象

如:

class Newstudent:
    __slots__ = ('name','age')
    def __init__(self,name,age):
        self.name=name
        self.age=age

if __name__ == "__main__":
    stu1 = Newstudent('alex',1000)
    #因爲使用__slots__指定了屬性,不能再進行綁定,
    # 出現AttributeError: 'Newstudent' object has no attribute 'nickname'
    # stu1.nickname = 'wusix',9000
    #AttributeError: 'Newstudent' object has no attribute 'nickname'
    #沒有__dict__因此出現AttributeError
    print('dict:',stu1.__dict__)
    #AttributeError: 'Newstudent' object has no attribute '__dict__'
   

三.屬性相關的特殊方法

  經過@property裝飾器能夠快速簡單的對屬性進行控制,可是可讀性差,所以,除了這種方式外,可使用python內置的一些特殊方法老控制屬性的存取,

這些方法見下表:

 

特殊方法 使用 描述
__getattr__(self,item) v = obj.n 返回obj對象的item屬性
__setattr__(self, key, value) obj.key = value 將obj對象的key屬性設置爲value
__delattr__(self,item) v = obj.n 刪除obj對象的item屬性
__dir__(self) dir(obj) 返回obj對象的屬性列表
__getattribute__(self,item) v = obj.n 返回obj對象的item屬性

例如經過上述方法對Student類中name屬性進行控制:

def __setattr__(self, key, value):
    if key == 'name':
        if not isinstance(value,str):
            raise AttributeError("form setarr:name must be s str obj")
        self.__name = value

若是類中同事定義了__seattr__和@name.setter,執行哪個?坑定是前者了.

'''
注意:若是要實現這些方法來對屬性存取進行控制,應該左海條件判斷,在設置的屬性或值不符合時拋出AttributeError或ValueError.
'''

__getattribute__()和_getattr__()方法都用於獲取屬性,在尋找屬性時,其中若是實現了則__getattr__()不會調用.而且__getattribute__()一般會致使遞歸調用,所以通常不須要實現該方法.

相關文章
相關標籤/搜索