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。因为是在类上调用,而非实例上调

用,因此类方法无法获得任何实例变量,只能获得类的引用。


你可能感兴趣的:(python进阶)