Python:在 Foo 类中:x = MyClass() MyClass 可以知道它所分配的变量的名称吗?

标签 python serialization metaclass

我希望能够执行以下操作:

class PrintName:
    def __init__( self, obj ):
        print obj._name

class SetName:
    def __init__( self, name = None ): # Default name is None
        self._name = name

class Test:
    f = SetName( ) # No explicit name given
    g = PrintName( f )

此时我希望 python 打印“f”,因此在执行 PrintName( f ) 时 f 应该知道它的名称。

我发现的每个自动命名解决方案都会在创建后给出属性的名称。 我一直在尝试用元类来解决这个问题,但即使这样似乎也不起作用。

我想这样做是为了能够“保存”和“重新加载”Python代码以供以后使用(有点像原始脚本语言,可以在使用时评估的程序中进行更改)

例如:

x = 0
y = 0
p = ( x, y )

打印 p 结果为 (0,0),然后对 x 和 y 执行一些操作,结果

x = 124
y = -32
p = ( x, y )

打印p变成(124,-32)。

最简单的方法是使用

p = ( 'x', 'y' )

但在这种情况下,我们如何知道“x”是变量的名称而不是字符串“x”

我尝试为此目的编写一种简单的脚本语言,但这需要大量工作,如果上述方法可行,那么整个 python 语言都可以在脚本中使用。

我正在尝试为我的问题找到一个简单而灵活的解决方案。

预先感谢您的帮助。

最佳答案

我设法使用 __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 的所有其他对象也会更改。 此外,我可以轻松地将代码保存到文本文件中以供以后使用。

这仍然需要工作,但这是一个好的开始。 我希望这能帮助其他人寻找类似的东西。

关于Python:在 Foo 类中:x = MyClass() MyClass 可以知道它所分配的变量的名称吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14667373/

相关文章:

python - 如何格式化符合 PEP8 的 python 断言语句?

c# - Objective C 和 C# 之间任意对象的二进制序列化?

json - WCF DataMember DateTime 序列化格式

python - 为多态身份增强 SQLAlchemy 语法

python - 异步循环 : how to implement asynio in an existing python program - and share variables/data?

python - RDD.take 不起作用

使用 kwargs 时的 Python 2 和 3 元类兼容性

groovy invokeMethod 将方法添加到元类需要 if 语句吗?

python - 将 pandas 中前 2 列最大值分组

c++ - 如何从 C++ 中的二进制数据包中提取 GUID?