用实例方法中的float替换实例?

时间:2012-08-12 04:42:20

标签: python class types python-2.7

我正在编写一个Python脚本来解析一些数据。目前我正在尝试创建一个创建“占位符”对象的类。我打算重复传递每个“占位符”变量,最后将其转换为 dict,float,list或string。由于需要一段时间来描述的原因,如果我可以通过调用方法替换实例,那将会容易得多。

这是一个简化的例子

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()

我完全理解我的“封印”方法中的“self”只是一个局部变量,并且不会对范围外的实例产生任何影响。但我不确定如何在实例中实现我想要的东西,这对我的代码来说最方便。我也理解我可以覆盖所有的bulit-ins( getItem toStr ),但这会使我的代码复杂化。

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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__,那么他们必须兼容转换才能实现)

然而,正如其他回答者指出的那样,一般来说这是一个非常糟糕的主意,即使有一种方法可以将每个引用转换为一个对象转换为另一个引用。我不会说从不这样做,但可能有合法使用这种技术(例如,我认为这是一种实现State Design Pattern而不创建的简单方法不必要的混乱)。

答案 2 :(得分:2)

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

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

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