我正在编写一个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菜鸟,所以我不确定这是否可行。放纵我,请:)
答案 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)
即使有一些理智的方式使它工作,我也会避免沿着这条路走下去,因为它会将对象的类型更改为与现有合同完全不兼容的东西。
现在,人们可以说“但我只在一个地方使用它,其他代码路径将永远不会看到旧合同”,但不幸的是,这不是这种机制的论据,因为你只能制作获得最终对象后,其他代码路径可用的值。
简而言之,不要这样做,甚至不要尝试。