包装Python对象

包装Python对象,python,Python,我想在plist格式之间序列化Python对象(这可以通过plistlib实现)。我的想法是编写一个类PlistObject来包装其他对象: def __init__(self, anObject): self.theObject = anObject 并提供“写入”方法: 现在,如果PlistObject的行为与包装对象本身一样,那就好了,这意味着所有属性和方法都以某种方式“转发”到包装对象。我意识到方法\uuuu getattr\uuuu和\uuuu setattr\uuuu可以

我想在plist格式之间序列化Python对象(这可以通过plistlib实现)。我的想法是编写一个类PlistObject来包装其他对象:

def __init__(self, anObject):
     self.theObject = anObject
并提供“写入”方法:

现在,如果PlistObject的行为与包装对象本身一样,那就好了,这意味着所有属性和方法都以某种方式“转发”到包装对象。我意识到方法
\uuuu getattr\uuuu
\uuuu setattr\uuuu
可以用于复杂的属性操作:

    def __getattr__(self, name):
         return self.theObject.__getattr__(name)
但是我当然遇到了这样一个问题,构造函数现在产生了一个无限递归,因为也
self.theObject=anObject
尝试访问包装的对象

我怎样才能避免这种情况?如果整个想法看起来不好,也告诉我

但是我当然遇到了一个问题,构造函数现在产生了一个无限递归,因为self.theObject=anObject也尝试访问包装的对象

这就是为什么手册建议您对所有“真实”属性访问都这样做的原因

theobj = object.__getattribute__(self, "theObject")
但是我当然遇到了一个问题,构造函数现在产生了一个无限递归,因为self.theObject=anObject也尝试访问包装的对象

这就是为什么手册建议您对所有“真实”属性访问都这样做的原因

theobj = object.__getattribute__(self, "theObject")

除非我遗漏了什么,否则这会很好:

def __getattr__(self, name):
    return getattr(self.theObject, name)

编辑:对于那些认为查找
self.theObject
将导致无限递归调用
\uuuu getattr\uuuu
的人,让我向您展示:

>>> class Test:
...     a = "a"
...     def __init__(self):
...         self.b = "b"
...     def __getattr__(self, name):
...         return 'Custom: %s' % name
... 
>>> Test.a
'a'
>>> Test().a
'a'
>>> Test().b
'b'
>>> Test().c
'Custom: c'

\uuuu getattr\uuuu
仅被称为。由于
可以在
中找到对象
,因此不会出现任何问题。

除非我遗漏了什么,否则这将正常工作:

def __getattr__(self, name):
    return getattr(self.theObject, name)

编辑:对于那些认为查找
self.theObject
将导致无限递归调用
\uuuu getattr\uuuu
的人,让我向您展示:

>>> class Test:
...     a = "a"
...     def __init__(self):
...         self.b = "b"
...     def __getattr__(self, name):
...         return 'Custom: %s' % name
... 
>>> Test.a
'a'
>>> Test().a
'a'
>>> Test().b
'b'
>>> Test().c
'Custom: c'

\uuuu getattr\uuuu
仅被称为。由于可以在
\uuu dict\uuuu
中找到
对象,因此不会出现任何问题。

我很高兴看到其他人能够帮助您递归调用
\uu getattr\uuu
。既然您要求对plist序列化的一般方法发表意见,我只想插嘴几点想法

Python的plist实现只处理基本类型,不提供扩展机制来指导它序列化/反序列化复杂类型。例如,如果您定义了自定义类,writePlist将无法提供帮助,因为您正在传递实例的
\uuuu dict\uuu
进行序列化

这有两个含义:

  • 如果不将包含其他非基本类型对象的任何对象转换为
    \uuuuuu dict\uuuuuu
    ,则无法使用此命令对整个网络图进行序列化,以此类推

  • 如果您使用自己的网络图漫游器来序列化所有可以访问的非基本对象,您将不得不担心图中的圆,其中一个对象在属性中有另一个对象,这反过来又会保留对第一个对象的引用,等等

  • 鉴于此,您可能希望看看pickle,因为它可以处理所有这些和更多问题。如果您出于其他原因需要plist格式,并且您确信可以坚持使用“简单”对象dict,那么您可能希望只使用一个简单的函数。。。试图让PlistObject模拟包含对象中的每个可能函数是一个洋葱头,可能有很多层,因为您需要处理包装实例的所有可能性

    像这样简单的东西可能更具python风格,并通过不首先包装来简化包装对象的可用性:

    def to_plist(obj, f_handle):
        writePlist(obj.__dict__, f_handle)
    

    我知道这看起来不太性感,但鉴于plist格式的严格限制,在我看来,它比包装器更易于维护,当然,这比人工强制应用程序中的所有对象从公共基类继承要好得多,因为在您的业务域中没有任何东西实际表明这些完全不同的对象是相关的。

    我很高兴看到其他人能够帮助您递归调用
    \uu getattr\uuu
    。既然您要求对plist序列化的一般方法发表意见,我只想插嘴几点想法

    Python的plist实现只处理基本类型,不提供扩展机制来指导它序列化/反序列化复杂类型。例如,如果您定义了自定义类,writePlist将无法提供帮助,因为您正在传递实例的
    \uuuu dict\uuu
    进行序列化

    这有两个含义:

  • 如果不将包含其他非基本类型对象的任何对象转换为
    \uuuuuu dict\uuuuuu
    ,则无法使用此命令对整个网络图进行序列化,以此类推

  • 如果您使用自己的网络图漫游器来序列化所有可以访问的非基本对象,您将不得不担心图中的圆,其中一个对象在属性中有另一个对象,这反过来又会保留对第一个对象的引用,等等

  • 鉴于此,您可能希望看看pickle,因为它可以处理所有这些和更多问题。如果您出于其他原因需要plist格式,并且您确信可以坚持使用“简单”对象dict,那么您可能希望只使用一个简单的函数。。。试图让PlistObject模拟包含对象中的每个可能函数是一个洋葱头,可能有很多层,因为您需要处理包装实例的所有可能性

    像这样简单的东西可能更具python风格,并通过不首先包装来简化包装对象的可用性:

    def to_plist(obj, f_handle):
        writePlist(obj.__dict__, f_handle)
    
    我知道这看起来不太性感,但在我看来它更容易维护