我需要保持它多少次实例化轨道Python类(I need a Python class that k

2019-07-29 12:10发布

我需要的是这样的一类:

>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3

这里是我的尝试:

class Foo(object):
    i = 0
    def __init__(self):
        Foo.i += 1

它的工作原理是必需的,但我不知道是否有一个更Python的方式来做到这一点。

Answer 1:

不。 这是相当不错的。

从Python中的禅:“简单比复杂好。”

这工作正常,是你在做什么明确的,不要把它复杂化。 也许它命名为counter什么的,但除此之外,你就可以尽可能Python的去走。



Answer 2:

装饰和元类的滥用。

def counting(cls):
    class MetaClass(getattr(cls, '__class__', type)):
        __counter = 0
        def __new__(meta, name, bases, attrs):
            old_init = attrs.get('__init__')
            def __init__(*args, **kwargs):
                MetaClass.__counter += 1
                if old_init: return old_init(*args, **kwargs)
            @classmethod
            def get_counter(cls):
                return MetaClass.__counter
            new_attrs = dict(attrs)
            new_attrs.update({'__init__': __init__, 'get_counter': get_counter})
            return super(MetaClass, meta).__new__(meta, name, bases, new_attrs)
    return MetaClass(cls.__name__, cls.__bases__, cls.__dict__)

@counting
class Foo(object):
    pass

class Bar(Foo):
    pass

print Foo.get_counter()    # ==> 0
print Foo().get_counter()  # ==> 1
print Bar.get_counter()    # ==> 1
print Bar().get_counter()  # ==> 2
print Foo.get_counter()    # ==> 2
print Foo().get_counter()  # ==> 3

你可以告诉它是由频繁使用双下划线的关键字的Python的。 (开玩笑,开玩笑...)



Answer 3:

如果你要担心线程安全(以便类变量可以从被实例化多个线程修改Foo ,上面的回答是正确S)。 我问线程安全性这个问题在这里 。 总之,你会做这样的事情:

from __future__ import with_statement # for python 2.5

import threading

class Foo(object):
  lock = threading.Lock()
  instance_count = 0

  def __init__(self):
    with Foo.lock:
      Foo.instance_count += 1

现在, Foo可以从多个线程被实例化。



文章来源: I need a Python class that keep tracks of how many times it is instantiated