2

我正在编写一个 Python 脚本来解析一些数据。目前我正在尝试创建一个创建“占位符”对象的类。我打算反复传递每个“占位符”变量,最后把它变成一个字典、浮点数、列表或字符串。由于需要一段时间来描述的原因,如果我可以通过调用方法来替换实例会容易得多。

这是一个简化的例子

class Event( dict ):

    def __init__( self ):

        self.sumA = 0.0
        self.sumB = 0.0

    def augmentA( self, i ):

        self.sumA += i

    def augmentB( self, i ):

        self.sumB += i

    def seal( self ):

        if self.sumA != 0 and self.sumB != 0:
            self = [ sumA, sumB ]

        elif self.sumA != 0:
            self = float( sumA )

        elif self.sumB != 0:
            self = float( sumB )

我想做的是:

e = Event()
e.augmentA( 1 )
e.augmentA( 2 )
e.seal()

...并让 'e' 变成一个浮点数。

我希望避免的是:

e = Event()
e.augmentA( 1 )
e.augmentA( 2 )
e = e.getSealedValue()

我完全理解我的“密封”方法中的“自我”只是一个局部变量,不会对范围外的实例产生任何影响。但是,我不确定如何从实例中实现我想要的,这对我的代码来说最方便。我也明白我可以覆盖所有的内置插件(getItemtoStr),但这会使我的代码复杂化很多。

我是一个 Python 菜鸟,所以我不确定这是否可能。请放纵我:)

4

3 回答 3

2

不,你不能通过调用一个方法来让一个变量值替换它自己。执行此操作的正常方法是您所说的:e = e.getSealedValue()

您可以使对象更改行为,但这通常被认为是一个坏主意,并且可能会导致代码高度不可维护。

于 2012-08-12T04:52:20.237 回答
2

在某些情况下,Python 允许您动态更改对象的类。但是,并非任何对象都可以转换为任何类,如下例所示(为便于阅读而添加了换行符):

>>> class A(object):
...   pass
...
>>> class B(object):
...   pass
...
>>> a = A()
>>> type(a)
<class '__main__.A'>

>>> a.__class__ = B
>>> type(a)
<class '__main__.B'>

>>> a.__class__ = int
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ assignment: only for heap types

(我不知道我脑海中的确切规则,但如果你的类使用__slots__例如它们必须兼容才能进行转换)

但是,正如其他回答者指出的那样,通常这样做是一个非常糟糕的主意,即使有一种方法可以将对一个对象的每个引用转换为对另一个对象的引用。我不会说永远不要那样做,这种技术可能有合法的用途(例如,我认为它是一种实现状态设计模式的简单方法,而不会造成不必要的混乱)。

于 2012-08-12T04:53:30.027 回答
2

即使有一些理智的方法可以让它工作,我也会避免走这条路,因为它会将对象的类型更改为与其现有合同完全不兼容的东西。

现在,有人可以说“但我只在一个地方使用它,其他代码路径永远不会看到旧合约”,但不幸的是,这不是这种机制的论据,因为你只能简单地使值可用一旦你有了最终的对象,其他代码路径。

简而言之,不要这样做,甚至不要尝试。

于 2012-08-12T04:54:42.257 回答