Python 簡明教程 --- 20,Python 類中的屬性與方法

微信公衆號:碼農充電站pro
我的主頁:https://codeshellme.github.iohtml

與客戶保持良好的關係可使生產率加倍。
—— Larry Bernstainpython

目錄git

在這裏插入圖片描述

類中的變量稱爲屬性,類中的函數稱爲方法github

類中的屬性分爲:shell

  • 實例屬性:對象全部,互不干擾
  • 類屬性:類全部,全部對象共享

類中的方法分爲:微信

  • 實例方法:定義中有self 參數
  • 類方法:定義中有cls 參數,使用@classmethod 裝飾器
  • 靜態方法:定義中即沒有self 參數,也沒有cls 參數,使用@staticmethod 裝飾器

1,實例屬性與類屬性

類的對象,就是類的一個實例。類的實例屬性被對象全部,包含在每一個對象之中,不一樣的對象之間,互不干擾。類的類屬性被類全部,被包含在類中,是全部的類對象共享。函數

在這裏插入圖片描述

通常狀況下,實例屬性會在__init__ 方法中聲明並初始化,而且使用self 來綁定。而類屬性是在類做用域中被聲明,而且不使用self 來綁定。code

例以下面代碼中,country 爲類屬性,__name 爲實例屬性:htm

#! /usr/bin/env python3

class People:

    country = 'china'

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

訪問實例屬性時使用對象.屬性名的格式,實例屬性屬於對象各自的,互不影響:對象

>>> p1 = People('小明')
>>> p2 = People('小美')
>>> 
>>> p1.get_name()
'小明'
>>> p2.get_name()
'小美'

類屬性被全部對象共有,一旦被改變,全部對象獲取到的值都會被改變。訪問類屬性時使用類名.屬性名的格式,也可使用對象.屬性名的格式來訪問:

>>> People.country              # 用`類名.屬性名`的格式訪問
'CHINA'
>>> p1.country                  # 用`對象.屬性名`的格式訪問
'china'
>>> p2.country
'china'
>>> 
>>> People.country = 'CHINA'    # 類屬性的值被改變
>>> p1.country                  # 每一個對象獲取到的值也會被改變
'CHINA'
>>> p2.country
'CHINA'

注意,在使用對象.屬性名的格式訪問對象時,不要以這種格式對類屬性進行賦值,不然結果可能不會像你想象的同樣:

>>> p1 = People('小明')
>>> p2 = People('小美')
>>> People.country
'china'
>>> p1.country
'china'
>>> p2.country
'china'
>>> p1.country = '中國'   # 使用`對象.屬性名`的格式對類對象進行賦值
>>> p1.country           # 只有 p1.country 被改變
'中國'
>>> p2.country           # p2.country 沒有被改變
'china'
>>> People.country       # People.country 也沒有被改變
'china'

從上面代碼中能夠看到,在Python 中以對象.屬性名格式對類屬性進行賦值時,只有p1.country 的值被改變了,p2.countryPeople.country 的值都沒有被改變。

實際上,這種狀況下,類屬性的值並無被改變,而是對象p1 中多了一個country 實例屬性,此後,p1.country 訪問的是p1 的實例屬性,p1.country對屬性country的訪問屏蔽了類中的country屬性,而p2.countryPeople.country 訪問的依然是原來的類屬性

因此,類名.屬性名對象.屬性名的格式均可以訪問類屬性的值,但儘可能避免使用對象.屬性名的格式對類屬性的值進行賦值,不然可能會發生混亂。

建議:

無論是訪問仍是改變類屬性的值,都只用類名.屬性名的格式

2,實例方法,類方法,靜態方法

Python 類中有三種方法:

  • 實例方法
  • 類方法
  • 靜態方法

實例方法屬於對象,方法中都有一個self 參數(表明對象自己)。實例方法只能由對象調用,不能經過類名訪問。實例方法中能夠訪問實例屬性和類屬性。

類方法屬於類,方法中都有一個cls 參數(表明類自己)。類方法便可以經過類名訪問,也能夠經過對象訪問,類方法中只能訪問類屬性,不能訪問實例屬性。

注意:

Python 解釋器在構造類與對象時,是先於對象產生的。

所以,類屬性與類方法是先於實例屬性與實例方法 產生的。

因此當類方法產生時,尚未實例屬性,所以,類方法中不能訪問實例屬性。

靜態方法中,沒有self 參數,也沒有cls 參數。所以,在靜態方法中,即不能訪問類屬性,也不能訪問實例屬性。靜態方法可使用類名訪問,也可使用對象訪問。

在Python 中,定義類方法須要用到裝飾器@classmethod,定義靜態方法須要用到裝飾器@staticmethod

實例方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

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

    # 實例方法中有self 參數
    def instance_method_test(self):
        # 在實例方法中訪問了實例屬性和類屬性
        print('name:%s country:%s' % (self.__name, People.country))

使用:

>>> p = People('小明')
>>> p.instance_method_test()
name:小明 country:china

在實例方法中訪問了實例屬性__name和類屬性country,都可以被訪問。

類方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

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

    # 類方法中都有cls 參數
    @classmethod
    def class_method_test1(cls):
        print('在類方法中訪問類屬性country:%s' % cls.country)

    @classmethod
    def class_method_test2(cls):
        print('在類方法中訪問實例屬性__name:%s' % self.__name)

使用:

>>> p = People('小明')
>>> p.class_method_test1()         # 在類方法中訪問類屬性,能夠
在類方法中訪問類屬性country:china
>>>
>>> p.class_method_test2()         # 在類方法中訪問實例屬性,出現異常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/wp/to_beijing/People.py", line 18, in class_method_test2
    print('在類方法中訪問實例屬性__name:%s' % self.__name)
NameError: name 'self' is not defined

從上面代碼中能夠看到,在類方法中能夠訪問類屬性,但在類方法中訪問實例屬性,會出現異常。

靜態方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

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

    # 靜態方法中即沒有self 參數也不沒有cls 參數
    @staticmethod
    def static_method_test1():
        print('在靜態方法中訪問類屬性country:%s' % cls.country)

    @staticmethod
    def static_method_test2():
        print('在靜態方法中訪問實例屬性__name:%s' % self.__name)

使用:

>>> p = People('小明')
>>> p.static_method_test1()      # 在靜態方法中訪問類屬性,出現異常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/wp/to_beijing/People.py", line 14, in static_method_test1
    print('在靜態方法中訪問類屬性country:%s' % cls.country)
NameError: name 'cls' is not defined
>>>
>>> p.static_method_test2()     # 在靜態方法中訪問實例屬性,出現異常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/wp/to_beijing/People.py", line 18, in static_method_test2
    print('在靜態方法中訪問實例屬性__name:%s' % self.__name)
NameError: name 'self' is not defined

從上面代碼中能夠看到,在靜態方法中不管訪問實例方法仍是類方法,都會出現異常。

3,專有方法

咱們以前講到過的魔法方法,即以雙下劃線__開頭且結尾的方法__xxx__,就是專有方法。這些方法都被Python 賦予了特殊的含義,用戶能夠根據須要,來實現這些方法。

下面咱們介紹一些 Python 中常見的專有方法。

__len__ 方法

實現該方法的類的對象,能夠用len() 函數計算其長度。

__str__ 方法

實現該方法的類的對象,能夠轉化爲字符串。

__call__ 方法

實現該方法的類的對象,能夠像函數同樣調用。

__iter__ 方法

實現該方法的類的對象,是可迭代的。

__setitem__ 方法

實現該方法的類的對象,能夠用索引的方式進行賦值。

__getitem__ 方法

實現該方法的類的對象,能夠用索引的方式進行訪問。

__contains__ 方法

實現該方法的類的對象,能夠進行in 運算。


__add__ 方法

實現該方法的類的對象,能夠進行加+運算。

__sub__ 方法

實現該方法的類的對象,能夠進行減-運算。

__mul__ 方法

實現該方法的類的對象,能夠進行乘*運算。

__div__ 方法

實現該方法的類的對象,能夠進行除/運算。

__pow__ 方法

實現該方法的類的對象,能夠進行乘方運算。

__mod__ 方法

實現該方法的類的對象,能夠進行取模運算。


__eq__ 方法

實現該方法的類的對象,能夠進行相等==比較。

__ne__ 方法

實現該方法的類的對象,能夠進行不等於!=比較。

__gt__ 方法

實現該方法的類的對象,能夠進行大於>比較。

__ge__ 方法

實現該方法的類的對象,能夠進行大於等於>=比較。

__lt__ 方法

實現該方法的類的對象,能夠進行小於<比較。

__le__ 方法

實現該方法的類的對象,能夠進行小於等於<=比較。

(完。)


推薦閱讀:

Python 簡明教程 --- 15,Python 函數

Python 簡明教程 --- 16,Python 高階函數

Python 簡明教程 --- 17,Python 模塊與包

Python 簡明教程 --- 18,Python 面向對象

Python 簡明教程 --- 19,Python 類與對象


歡迎關注做者公衆號,獲取更多技術乾貨。

碼農充電站pro

相關文章
相關標籤/搜索