Dies könnte funktionieren - fügen Sie die Klasse Attribut, wenn es nicht bereits existiert eine Metaklasse mit:
foo.py:
def load_stuff():
return {'foo':1, 'bar':2}
class F(type):
def __new__(meta, name, bases, namespace):
if 'cache' not in namespace:
print('adding cache')
namespace['cache'] = load_stuff()
return super().__new__(meta, name, bases, namespace)
class MyCache(metaclass = F):
def __init__(self):
print(len(MyCache.cache))
test.py:
print(__name__)
import foo
print(foo.MyCache.cache)
print('********************')
tmp.py:
>>> import tmp
tmp.py
adding cache
*******************
test
{'foo': 1, 'bar': 2}
********************
>>> tmp.foo.MyCache.cache
{'foo': 1, 'bar': 2}
>>> tmp.test.foo.MyCache.cache
{'foo': 1, 'bar': 2}
>>> tmp.test.foo.MyCache.cache['x'] = 'x'
>>> tmp.test.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x'}
>>> tmp.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x'}
>>>
>>> tmp.foo.MyCache.cache is tmp.test.foo.MyCache.cache
True
>>>
>>> import test
test
adding cache
{'foo': 1, 'bar': 2}
********************
>>> test.foo.MyCache.cache
{'foo': 1, 'bar': 2}
>>>
>>> import tmp
tmp.py
*******************
>>>
>>> tmp.foo.MyCache.cache
{'foo': 1, 'bar': 2}
>>>
>>> tmp.foo.MyCache.cache['x'] = 'x'
>>> tmp.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x'}
>>> test.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x'}
>>>
>>> z = tmp.foo.MyCache()
3
>>> z.cache
{'foo': 1, 'bar': 2, 'x': 'x'}
>>>
>>> z.cache['y'] = 'y'
>>> z.cache
{'foo': 1, 'bar': 2, 'x': 'x', 'y': 'y'}
>>> test.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x', 'y': 'y'}
>>> tmp.foo.MyCache.cache
{'foo': 1, 'bar': 2, 'x': 'x', 'y': 'y'}
>>>
>>> tmp.foo.MyCache.cache is test.foo.MyCache.cache
True
Ich begann zu denken und erkennen, dass das Klassenattribut auch ein Singleton sein könnte, die von dict erbt.
temp.py und test.py - wie oben
foo.py:
def load_stuff():
return [('a', 1), ('b', 2)]
class Borg:
_shared_state = {}
def __new__(cls, *a, **k):
obj = super().__new__(cls, *a, **k)
obj.__dict__ = cls._shared_state
return obj
class Cache(dict, Borg):
pass
class OneCache(metaclass = F):
cache = Cache(load_stuff())
def __init__(self):
print(len(OneCache.cache))
Dann:
>>> import tmp
>>> tmp.foo.OneCache.cache
{'a': 1, 'b': 2}
>>> tmp.test.foo.OneCache.cache
{'a': 1, 'b': 2}
>>> z = tmp.foo.OneCache()
2
>>> z.cache['r'] = 't'
>>> z.cache
{'a': 1, 'b': 2, 'r': 't'}
>>> tmp.foo.OneCache.cache
{'a': 1, 'b': 2, 'r': 't'}
>>> tmp.test.foo.OneCache.cache
{'a': 1, 'b': 2, 'r': 't'}
>>>
>>> tmp.foo.OneCache.cache is tmp.test.foo.OneCache.cache is z.cache
True
>>>
Was ist 'B' in * Alle Instanzen von B sollte * ein "Cache" teilen? –
Die Namespaces sind unterschiedlich. –
Mein schlechtes (bezogen auf meine gelöschte Antwort). Ich denke, es würde keinen Sinn ergeben, wenn beide nicht anders gedruckt würden. – Dair