Python中函数的静态成员? [复制]

Posted

技术标签:

【中文标题】Python中函数的静态成员? [复制]【英文标题】:Static member of a function in Python ? [duplicate] 【发布时间】:2011-12-28 00:47:57 【问题描述】:

可能重复:Static class variables in PythonWhat is the Python equivalent of static variables inside a function?

如何在 Python 中使用静态字段?

例如,我想计算该函数被调用了多少次 - 我该怎么做?

【问题讨论】:

@PaulManta:我不同意。您的链接与类静态字段无关(如 OP 所说),而是与“ 函数级别的静态成员,而不是类级别 ”,正如 OP 在您给出的问题中所述使用链接。 @Tadeck 'class' 这个词甚至没有出现在问题中......但是短语'static member of a function'确实出现了。 @PaulManta:请再次阅读您链接到的问题 - 有两个词:“classandfunction我>“。在当前问题(this question)中有对“static fields”的引用。正因为如此,并且因为我从未听说过“static fields”引用函数中的静态变量,但我听说过“static fields”引用静态类的成员变量,我假设当前的问题是关于类的静态成员变量。除非你证明不是这样,否则我认为我的第一条评论的赞成票意味着对此事的一些支持。 @Tadeck 关于投票:对你有好处,这里有两个互联网积分。说真的,争论什么?这个例子很清楚,他想知道如何计算一个函数被调用了多少次。由于没有更好的术语,他使用了相当不正确的“静态字段”,但从示例和标题中仍然可以清楚地看出他的意图。问题出在哪里? @Tadeck 'class'这个词appears 在这种情况下,'如何在函数级别实现静态成员,相对于类级别'。哈哈,你在这件事上做了这么大的事。 【参考方案1】:

如果你想计算一个方法被调用了多少次,无论是哪个实例调用它,你都可以使用这样的类成员:

class Foo(object):
    calls=0            # <--- call is a class member
    def baz(self):
        Foo.calls+=1

foo=Foo()
bar=Foo()
for i in range(100): 
    foo.baz()
    bar.baz()
print('Foo.baz was called n times'.format(n=foo.calls))
# Foo.baz was called 200 times

当你这样定义calls时:

class Foo(object):
    calls=0            

Python 将键值对 ('calls', 0) 放入 Foo.__dict__

可以通过Foo.calls访问Foo 的实例,例如foo=Foo(),也可以使用foo.calls 访问它。

要将新值分配Foo.calls,您必须使用Foo.calls = ...。 实例不能使用 foo.calls = ...,因为这会导致 Python 在 foo.__dict__ 中放置一个新的不同的键值对,其中保留了实例成员。

【讨论】:

【参考方案2】:

以下是计算同一类的所有对象的调用次数的示例:

class Swallow():
    i = 0 # will be used for counting calls of fly()
    def fly(self):
        Swallow.i += 1

这就是证据:

>>> a = Swallow()
>>> b = Swallow()
>>> a.fly()
>>> a.i
1
>>> Swallow.i
1
>>> b.fly()
>>> b.i
2
>>> Swallow.i
2

所以你可以通过给出对​​象名或类名来阅读它。

【讨论】:

【参考方案3】:

这是一个向函数添加计数的装饰器。

import functools

def count_calls(func):
    @functools.wraps(func)
    def decor(*args, **kwargs):
        decor.count += 1
        return func(*args, **kwargs)
    decor.count = 0
    return decor

用法:

>>> @count_calls
... def foo():
...     pass
...
>>> foo.count
0
>>> foo()
>>> foo.count
1

【讨论】:

装饰器最好叫count_calls 这是最复杂的方法,不是吗? @Patryk:一点也不;定义装饰器意味着您可以通过在函数定义前添加一行来计算对任意数量的函数的调用。使用 class 属性来计算对方法的调用并不能这样概括(它可以,但它最终会等同于装饰器解决方案,更冗长,并且可能更慢)。【参考方案4】:

这是一种简单的方法:

def func():
    if not hasattr(func, 'counter'):
        func.counter = 0
    func.counter += 1
    counter = 0 # Not the same as `func.counter`
    print(func.counter)

或者,如果您不喜欢在每次调用时都执行 if,您可以这样做:

def func():
    func.counter += 1
    print(func.counter)
func.counter = 0

【讨论】:

以上是关于Python中函数的静态成员? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

类函数、成员函数、静态函数、抽象函数、方法伪装属性

在 C++0x 中,非静态数据成员初始化器会覆盖隐式复制构造函数吗?

python成员函数如何调用静态函数

Python - 静态函数(staticmethod), 类函数(classmethod), 成员函数 区别(完全解析)

python 为啥要使用静态方法

我可以举一个现实生活中的例子,其中非静态成员函数不访问通过空指针调用的对象会导致可观察到的问题吗? [复制]