のためのPythonの文字列のインターンの機能を複製しようとすると、私のような何かやってみたかった:自己のプロジェクトのために非文字列
class Species(object): # immutable.
def __init__(self, id):
# ... (using id to obtain height and other data from file)
def height(self):
# ...
class Animal(object): # mutable.
def __init__(self, nickname, species_id):
self.nickname = nickname
self.species = Species(id)
def height(self):
return self.species.height()
をあなたが見ることができるように、私は本当にの複数のインスタンスを必要としません。 IDごとの種(id)が、そのIDを持つAnimalオブジェクトを作成するたびに作成していますが、おそらくAnimal(somename, 3)
という複数の呼び出しが必要です。私は何をしようとしている、それを解決するために
は、それの2つのインスタンスのために、のは、aとbを言わせようにクラスを作ることです、次は常に真である:
(a == b) == (a is b)
これは何かでありますPythonは文字列リテラルで行い、インターンシップと呼ばれます。例:
a = "hello"
b = "hello"
print(a is b)
この印刷は真(私たちがPythonシェルを直接使用している場合は文字列が十分短い場合)になります。
私はCPythonがどのようにこれを行うのかを推測することができます。これまでのところ私が持っている:
class MyClass(object):
myHash = {} # This replicates the intern pool.
def __new__(cls, n): # The default new method returns a new instance
if n in MyClass.myHash:
return MyClass.myHash[n]
self = super(MyClass, cls).__new__(cls)
self.__init(n)
MyClass.myHash[n] = self
return self
# as pointed out on an answer, it's better to avoid initializating the instance
# with __init__, as that one's called even when returning an old instance.
def __init(self, n):
self.n = n
a = MyClass(2)
b = MyClass(2)
print a is b # <<< True
は、私の質問は以下のとおりです。
a)の解決にも価値が私の問題ですか?私の意図するSpeciesオブジェクトは非常に軽量で、最大の時間でなければならないので、動物はかなり制限されています(ポケモンのゲームを想像してください:1000以上のインスタンス、トップス)
b)私の問題を解決する有効なアプローチ?
c)有効でない場合は、この問題を解決するために、もっとシンプルで洗練された方法を詳しく教えてください。
さまざまな '' functools.lru_cache'のための ''ラッパー ''(https://hg.python.org/cpython/file/3.5/Lib/functools.py#l453)です。それが起こると、上記の私のコメントをサポートしている原子的な作業では "原子的"操作のためにロックされませんが、 "ロックでキャッシュから取得しようとすると、失敗した場合はロックを解除し、キャッシュされたサイズに対して上記で使用されたパターンは制限されています(また、グループはアトミックに実行する必要があります)。 – ShadowRanger