首页
学习
活动
专区
工具
TVP
发布

Python的静态方法

静态方法

有时候,我们需要处理与类而不是与实例相关的数据。比如记录由类生产实例的数目,这种信息与类相关,而与实例无关,也就是说,这种信息通常存储在类自身上,不需要由实例来处理。

对于这样的任务,一个类之外的简单函数可以胜任。然而,要更好地把这样的代码与一个类联系起来,并且允许这样的过程可以继承,在类自身之中编写这类函数将会更好。为了做到这一点,我们需要一个类中的方法没有self实例参数。

静态方法可以用来实现这一目标:静态方法就是嵌入在类中没有self参数的函数,并且旨在操作类属性而不是实例属性。

在Python3以后的版本中,如果方法只通过一个类调用的话,我们没必要将这样的方法声明为静态的,但是要通过一个实例来调用它,我们就必须这样做。

例如,我们想使用类特性去计算从一个类产生了多少实例。下面的spam.py模块把一个计数器作为类特性,每次创建一个新的实例,初始化函数都会对计数器加1,还有另外一个方法用于显示计数器的值。记住,类属性是由所有实例共享。

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances = Spam.numInstances+1

def printNumInstances():

print("Number of instancescreated:",Spam.numInstances)

方法printNumInstances旨在打印类数据而不是实例数据,它关乎所有实例而非某个特定实例。因此,我们想要不传递一个实例就可以调用它。实际上,如果想生成一个实例来获取实例数目,是会改变要获取的实例数目的!我们想要一个无self的静态方法。

我们来运行一下看看:

>>> a =Spam()

>>> b =Spam()

>>> c =Spam()

>>>Spam.printNumInstances()

Number ofinstances created: 3

直接通过类来调用方法是可以的。

>>>a.printNumInstances()

Traceback (mostrecent call last):

File "

", line 1,in

a.printNumInstances()

TypeError:printNumInstances() takes 0 positional arguments but 1 was given

通过实例来调用方法则会出错:printNumInstances()没有位置参数,但却传递了一个参数。如果我们希望用实例来调用并且得出正确答案,可以使用内建的函数staticmethod:

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances = Spam.numInstances+1

def printNumInstances():

print("Number of instancescreated:",Spam.numInstances)

printNumInstances =staticmethod(printNumInstances)

来调用一下:

>>> a,b,c= Spam(),Spam(),Spam()

>>>Spam.printNumInstances()

Number of instances created: 3

>>>a.printNumInstances()

Number ofinstances created: 3

通过staticmethod函数作用后,静态方法圆满解决了问题。我们把staticmethod函数称作装饰器函数,可以这样标记:

@staticmethod

defprintNumInstances():

print("Number of instancescreated:",Spam.numInstances)

它与等效与:

defprintNumInstances():

print("Number of instancescreated:",Spam.numInstances)

printNumInstances =staticmethod(printNumInstances)

所以,可以把类写成:

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances = Spam.numInstances+1

@staticmethod

def printNumInstances():

print("Number of instancescreated:",Spam.numInstances)

验证一下结果:

>>> a,b,c =Spam(),Spam(),Spam()

>>>Spam.printNumInstances()

Number of instances created: 3

>>>a.printNumInstances()

Number of instances created: 3

没问题!

当然,你也可以把这个printNumInstances()函数放在类外来实现,但此法有一些瑕疵:

首先,它给该文件的作用域添加了一个额外的名字,此外该函数与类直接关联很小,而

且次函数不能通过继承定制,它们位于类的名字空间之外:子类不能通过重新定义这样

的一个函数来直接替代或扩展它。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190215G17UZL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券