:私はそれがインスタンス化される回数のトラックを保つPythonのクラスが必要
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
それは、必要に応じて動作します。ここでは
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
は私の試みですしかし、私はそれを行うためにもっとpythonicな方法があるのだろうかと思います。
:私はそれがインスタンス化される回数のトラックを保つPythonのクラスが必要
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
それは、必要に応じて動作します。ここでは
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
は私の試みですしかし、私はそれを行うためにもっとpythonicな方法があるのだろうかと思います。
いいえ。それはかなり良いです。
From The Python of Zen:「シンプルは複雑なものより優れています。
それはうまく動作し、あなたがやっていることではっきりしていて、それを複雑にしません。たぶんそれはcounter
か何かと名付けられますが、それ以外にはあなたはpythonicに行くのが良いと言います。
デコレータとメタクラスの悪用。
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
二重の下線付きの名前を頻繁に使用することでPythonicと言うことができます。
+1:これは嫌です。 – Thomas
クラス変数がFoo
をインスタンス化している複数のスレッドから変更できるように、スレッドの安全性を心配したい場合は、上記の答えが正しいです。私はスレッドの安全性についてこの質問をしましたhere。要約すると、あなたはこのような何かしなければならないでしょう。今Foo
を
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
を複数のスレッドからインスタンス化することができます。
pythonicとは何ですか?それはPythonで動作する場合は...そのPythonではない** ic **? – Victor
他の方法を実装する時間を無駄にする必要はありません – fuentesjr
私は「python」を「pythonイディオム」を意味すると解釈します。 JavaプログラマのようにPythonを書くことは可能です。これは、必ずしも最高の品質やスタイルを示すわけではありません。 – duffymo