1. 程式人生 > >python進階14:例項方法和類方法、types.MethodType()

python進階14:例項方法和類方法、types.MethodType()

1 例項方法

  一個例項的私有屬性就是以__開頭的屬性,無法被外部訪問,那這些屬性定義有什麼用?雖然私有屬性無法從外

部訪問,但是,從類的內部是可以訪問的。除了可以定義例項的屬性外,還可以定義例項的方法。例項的方法就是在

類中定義的函式,它的第一個引數永遠是 self,指向呼叫該方法的例項本身,其他引數和一個普通函式是完全一樣

的:

class Person(object):

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

    def get_name(self):
        return self.name
  get_name(self) 就是一個例項方法,它的第一個引數是self。__init__(self, name)其實也可看做是一個特殊的

例項方法。呼叫例項方法必須在例項上呼叫:

>>> p1 = Person('Bob')
>>> print p1.get_name() #self不需要傳入
Bob
  在例項方法內部,可以訪問所有例項屬性,這樣,如果外部需要訪問私有屬性,可以通過方法呼叫獲得,這種數

據封裝的形式除了能保護內部資料一致性外,還可以簡化外部呼叫的難度。

2 types.MethodType() 
  因為方法也是一個屬性,所以,它也可以動態地新增到例項上,只是需要用 types.MethodType() 把一個函式變

為一個方法:

import types
def fn_get_grade(self):
    if self.score >= 80:
        return 'A'
    if self.score >= 60:
        return 'B'
    return 'C'

class Person(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

  下面我們將fn_get_grade()方法新增到例項上:

>>> p1 = Person('Bob', 90)
>>> p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
>>> print p1.get_grade()
A
>>> p2 = Person('Alice', 65)
>>> print p2.get_grade()
# ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
  因p2例項沒有繫結get_grade方法,所以出現錯誤。
3 定義類方法

  和屬性類似,方法也分例項方法類方法

  在class中定義的全部是例項方法,例項方法第一個引數 self 是例項本身。定義類方法需要在方法前加上

@classmethod

class Person(object):
    count = 0
    @classmethod
    def how_many(cls):
        return cls.count
    def __init__(self, name):
        self.name = name
        Person.count = Person.count + 1

print Person.how_many()
p1 = Person('Bob')
print Person.how_many()
  通過標記一個 @classmethod,該方法將繫結到 Person 類上,而非類的例項。類方法的第一個引數將傳入類本

身,通常將引數名命名為 cls,上面的 cls.count 實際上相當於 Person.count。因為是在類上呼叫,而非例項上調

用,因此類方法無法獲得任何例項變數,只能獲得類的引用。