1. 程式人生 > >Python學習:17.Python面向對象(四、屬性(特性),成員修飾符,類的特殊成員)

Python學習:17.Python面向對象(四、屬性(特性),成員修飾符,類的特殊成員)

介紹 col 寫代碼 被調用 表示 1.5 emp 成員 object

一、屬性(特性)

普通方法去執行的時候,後面需要加括號,特性方法執行的時候和靜態字段一樣不需要不需要加括號.

特性方法不和字段同名.

特性方法不能傳參數.

在我們定義數據庫字段類的時候,往往需要對其中的類屬性做一些限制,一般用get和set方法來寫,那在python中,我們該怎麽做能夠少寫代碼,又能優雅的實現想要的限制,減少錯誤的發生呢,這時候就需要我們的@property.

獲取特性

class Foo:

    def __init__(self,name):
        self.name = name

    # 普通方法
    def start(self):
        temp 
= %s sb %self.name return temp # 特性,將方法的執行方式變為和字段一樣 @property def end(self): temp = %s gd%self.name return temp obj = Foo(alexsel) ret1 = obj.start() ret2 = obj.end print(ret2) print(obj.name) 輸出結果: alexsel gd alexsel

設置特性

設置特性方法的時候,所需要加的裝飾器名字規則是,你所設置特性方法名字點setter(例如:@end.setter)

class Foo:

    def __init__(self,name):
        self.name = name

    # 普通方法
    def start(self):
        temp = %s sb %self.name
        return temp

    # 特性,將方法的執行方式變為和字段一樣
    @property
    def end(self):
        temp = %s gd%self.name
        return temp

    # 如果需要使用設置特性的的方法,就需要這個點前面名字和所要設置特性的方法同名,就像這裏的end
@end.setter def end(self,value): print(value) self.name = value obj = Foo(alexsel) #獲取特性,獲取特性的時候,拿到的是@Property的返回值 ret2 = obj.end print(ret2) #設置特性,設置特性的時候,會執行@end.setter下面的方法,這個‘aaa‘就傳遞給value obj.end = aaa ret1 = obj.end print(ret1) 輸出結果: alexsel gd aaa aaa gd

這個特性在python中不是特別常用,因為我們一般可以使用普通的方法代替特性方法。

二、成員修飾符

首先介紹‘__’,這個在命名之前添加就會變成私有的,只有在類的內部才能訪問。

class Foo:

    book = alexsel
    #命名的時候前面添加__,只有在類的內部才能訪問,在外部無法訪問
    __book = book

    def __init__(self):
        self.__name = alexsel


    def start(self):
        print(Foo.__book)
        print(self.__name)


    def __end(self):
        print(__end)


obj = Foo()
print(obj.book)
# print(obj.__book) #這種無法拿到字段
#在外部也無法調用類私有方法
#obj.__end()
#通過內部方法調用拿到字段
obj.start()


輸出結果:
alexsel
book
alexsel

私有的屬性只有自己可以訪問,當某個類繼承這個類之後,也無法訪問父類的私有屬性。

class Foo:

    book = alexsel
    __book = book

    def __init__(self):
        self.__name = alexsel


    def start(self):
        print(Foo.__book)
        print(self.__name)
        self.__end()


    def __end(self):
        print(__end)


class Bar(Foo):
    def start(self):
        print(self.__name)#子類繼承父類,也無法調用父類的私有屬性


obj = Bar()
obj.start()

輸出結果:
報錯

靜態方法也是如此

class Foo:

    book = alexsel
    __book = book

    def __init__(self):
        self.__name = alexsel


    def start(self):
        Foo.__add() #內部調用私有靜態方法


    def __end(self):
        print(__end)


    @staticmethod
    def __add():
        print(add)


obj = Foo()
obj.start()


輸出結果:
add

python成員修飾符有兩種,一種是共有的,一種是私有的,共有的都可以訪問,私有的只有自己可以訪問,或者在外部間接訪問。

但是還有一種強行訪問私有屬性的方法,如下:

class Foo:

    book = alexsel
    __book = book

    def __init__(self):
        self.__name = alexsel


    def start(self):
        Foo.__add() #內部調用私有靜態方法


    def __end(self):
        print(__end)


    @staticmethod
    def __add():
        print(add)


obj = Foo()
print(obj._Foo__book)


輸出結果:
book

雖然可以使用,但是不推薦這種使用方法。

三、類的特殊成員

1.call

__call__()的作用是使實例能夠像函數一樣被調用,同時不影響實例本身的生命周期(__call__()不影響一個實例的構造和析構)。

__call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()。

class Foo:

    def __init__(self):
        print( Foo:      def init)

    def __call__(self, *args, **kwargs):
        print(call)
        return 1
r = Foo()
r()
r = Foo()()#加第一個括號執行__init__,執行完__init__,獲取到一個對象,對象加一個括號就是執行__call__,拿到返回值
print(r)


輸出結果:
init
call
init
call
1

類後面添加括號執行__init__方法,對象後面加括號執行__call__方法。

2.getitem,setitem,delitem

用於索引操作,如字典。以上分別表示獲取、設置、刪除數據。

首先得實例是字典類型的操作。

class Foo:

    def __init__(self):
        print(init)

    def __call__(self, *args, **kwargs):
        print(call)
        return 1

    def __getitem__(self, item):
        print(item)

    def __setitem__(self, key, value):
        print(key,value)

    def __delitem__(self, key):
        print(key)

r = Foo()
r() #調用__call__方法
r[k1]#使用中括號傳參數的時候,默認使用過的是__getitem__方法
r[xxx] = 123#這裏的xxx傳給__setiem__的key,123傳給__setitem__的value。
del r[xxx]    #刪除的時候,調用的是__delitem__方法


輸出結果:
init
call
k1

接下來是切片類型的操作,在切片操作的時候,在2.x版本中,執行的是__getslice_,__setslice__,delslice__方法,在3.x中的版本執行的是還是__getitem__,__setitem__,__delitem__方法。

class Foo:

    def __init__(self):
        print(init)

    def __call__(self, *args, **kwargs):
        print(call)
        return 1

    def __getitem__(self, item):
        print(item,type(item),__getitem__)

    def __setitem__(self, key, value):
        print(key,value)

    def __delitem__(self, key):
        print(key)

r = Foo()
#使用切片的時候,在2.x版本中,調用的是__getslice__方法,在3.x中調用的是__getitem__方法。
r[1:3]
r[1:3] = [11,22,33] #這裏執行__setitem__方法
del r[1:3]  #在這裏執行__delitem__方法

3.dict

dict是用來存儲對象屬性的一個字典,其鍵為屬性名,值為屬性的值。

class Foo:
    """
    我是一個註釋
    """

    book = alexsel
    __book = book

    def __init__(self):
        self.__name = alexsel


    def start(self):
        Foo.__add() #內部調用私有靜態方法


    def __end(self):
        print(__end)


    @staticmethod
    def __add():
        print(add)


obj = Foo()
print(obj.__dict__) #獲取對象裏面所有字段
print(Foo.__dict__)

輸出結果:
{_Foo__name: alexsel}
{book: alexsel, _Foo__book: book, __init__: <function Foo.__init__ at 0x00000000027CF950>, __dict__: <attribute __dict__ of Foo objects>, start: <function Foo.start at 0x00000000027EBB70>, _Foo__add: <staticmethod object at 0x00000000027B6390>, __weakref__: <attribute __weakref__ of Foo objects>, _Foo__end: <function Foo.__end at 0x00000000027EBBF8>, __doc__: \n    我是一個註釋\n    , __module__: __main__}

4.__iter__

類的叠代器可以使用for循環叠代類。

如果創建的對象可以被叠代,在類的內部就執行了__iter__方法。

class Foo:
    def __iter__(self):
        yield 1
        yield 2
        yield 3
        yield 4


obj = Foo()
#如果執行for對象時,自動會執行對象的iter方法
for i in obj:
    print(i)



輸出結果:
1
2
3
4

Python學習:17.Python面向對象(四、屬性(特性),成員修飾符,類的特殊成員)