我设法使用__ prepare __在 Python 3.x 中找到了解决方案。这是一个解释我想要做什么的工作代码。
from collections import MutableMapping
class MDict(MutableMapping):
def __init__(self, *args, **kwargs):
self._d = dict(*args, **kwargs)
def __getitem__(self, key):
return self._d[key]
def __setitem__(self, key, value):
self._d[key] = value
try:
self._d[key]._key = key # Let's set the name of the object
except AttributeError: # Not a good way to handle immutable objects
pass
def __delitem__(self, key):
del self._d[key]
def __iter__(self):
return iter(self._d)
def __len__(self):
return len(self._d)
class MBase(type):
@classmethod
def __prepare__(metacls, name, bases, **kwargs):
return MDict()
def __new__(metacls, name, bases, mdct):
return super().__new__(metacls, name, bases, dict(mdct))
def __str__( self ):
return "class {0}(CSub, metaclass=MBase):".format( self.__name__ )
class CSub: # An empty class so we know when to go deeper int print_code
pass
class Integer:
def __init__( self, value ):
self._value = value
def __str__( self ):
try: # See if it's a reference
return "{0} = Integer( {1} )".format( self._key, self._value._key )
except: # Not it's a number
return "{0} = Integer( {1} )".format( self._key, self._value )
class Point:
def __init__( self, x, y ):
if type( self ) == type( x ): # Check to see if initializing with a reference
self._x, self._y = x._key, y._key
else: # It's not reference
self._x, self._y = x, y
def __str__( self ):
try:
return "{0} = Point( {1}, {2} )".format( self._key, self._x._key, self._y._key )
except:
return "{0} = Point( {1}, {2} )".format( self._key, self._x, self._y )
def print_code( cls, indent = 2 ):
# Print the header
if indent == 2:
print( "class Main(metaclass=MBase):" )
for attr, value in cls.__dict__.items():
if not attr.startswith( "_" ): # Ignore hidden attributes
print( " " * indent + str( value ) ) # Use indentation
if isinstance( value, CSub.__class__ ): # If it's a subclass then process that too
print_code( value, indent + 2 )
class Main(metaclass=MBase):
x = Integer( 0 )
y = Integer( 100 )
z = Integer( x )
p1 = Point(x,x)
p2 = Point(y,y)
class Sub(CSub, metaclass=MBase):
p = Point(1,1)
print_code( Main )
这样,如果我更改对象 x,那么引用 x 的所有其他对象也会更改。更重要的是,我可以轻松地将代码保存到文本文件中以备后用。
这仍然需要工作,但这是一个好的开始。我希望这会帮助其他人寻找类似的东西。