python 静态方法、类方法(二)

《Python静态方法、类方法》一文中曾用在类之外生成函数的方式,来计算类的实例的个数。本文将探讨用静态方法和类方法来实现此功能。

一使用静态方法统计实例

例1.static.py

# -*- coding:utf-8 -*-
class Spam:
    numInstance = 0

    def __init__(self):
        Spam.numInstance += 1

    def printNumInstance():
        print 'Number of instance:', Spam.numInstance

    printNumInstance = staticmethod(printNumInstance)  # 使用内建函数staticmethod将函数变为静态函数

调用结果:

>>> from static import Spam  # 导入类
>>> a, b, c = Spam(), Spam(), Spam()  #实例化
>>> Spam.printNumInstance()  # 类调用
Number of instance: 3
>>> a.printNumInstance()  # 实例调用,实例参数没有被传入
Number of instance: 3

静态方法调用相对于将PirntNumInstance移到类之外的方法相比较,有以下优点:

1.静态方法把函数名称变成类作用域内的局部变量,使得函数名不会与模块内的其它变量名相冲突。

2.把函数程序代码迁移到其靠近使用的地方,易于寻找。

3.允许子类定制静态方法。如例2所示。

例2.custom_made.py

class Sub(Spam):  # 子类Sub
    def printNumInstance():  # 重新定义
        print 'Extra stuff...'
        Spam.printNumInstance()

    printNumInstance = staticmethod(printNumInstance)

调用结果:

>>>a, b = Sub(), Sub()  # 实例化
>>> a.printNumInstance()  #实例调用
Extra stuff...
Number of instance: 2  #重新启动解释器,进行调用。否则应该为5,因为前面已经有三个实例
>>> Sub.printNumInstance() #类调用
Extra stuff...
Number of instance: 2

此外,类可以继承方法而不用重新定义,如下:

>>> class Other(Spam):  # 完全继承静态方法
...     pass
...     
>>> c = Other()
>>> c.printNumInstance()
Number of instance: 3

 

二、使用类方法统计实例

 例3:a_class.py

#-*- coding:utf-8 -*-

class Spam:
    numInstance = 0

    def __init__(self):
        Spam.numInstance += 1

    def printNumInstance(cls):  # 接收实例的(最底层)类作为参数,传入cls中
        print 'Number of instance:', cls.numInstance

    printNumInstance = classmethod(printNumInstance)

调用结果:

>>> from a_class import Spam #导入模块
>>> a, b = Spam(), Spam()  #实例化
>>> a.printNumInstance()  #实例调用,传入实例a所在的最底层的类Spam
Number of instance: 2
>>> Spam.printNumInstance()  # 类调用,传入类Spam
Number of instance: 2

三总结

由于类方法总是接收一个实例化的类的最底层的类:

1.静态方法:适用于处理一个类的本地数据

2.类方法:适用于处理类层级中每个类的数据

 

下面的例子(例4)展示了利用类方法管理每个类的实例计数器。例4的代码中,顶层的超类使用一个类方法来管理状态信息,该信息根据树中的类不同而不同,而且储存在类上。

例4:test.py

class Spam:
    numInstance = 0
    
    def count(cls):
        cls.numInstance += 1
    
    def __init__(self):
        self.count()
    
    count = classmethod(count)
    

class Sub(Spam):
    numInstance = 0
    
    def __init__(self):
        Spam.__init__()
        

class Other(Spam):
    numInstance = 0

调用结果:

>>>x = Spam()
>>>y1, y2 = Sub(), Sub()
>>>z1, z2, z3 = Other(), Other(), Other()
>>>x.numInstance, y1.numInstance, z1.numInstance
1, 2, 3
>>>Spam.numInstance, Sub.numInstance, Other.numInstance
1, 2, 3
posted @ 2016-05-15 04:51  shawshanks  阅读(563)  评论(0编辑  收藏  举报