2012-08-12 23 views
2

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

这里有一个简单的例子

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

我完全明白“自我”在我的“密封”方法仅仅是一个局部变量,并且不会对实例的任何影响外部范围。但我不确定如何实现我想要的内容,从实例中,对于我的代码来说最方便。我也明白我可以覆盖所有的插件(getItem,toStr),但这使我的代码变得复杂了很多。

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

+0

对于无聊的问题,我表示歉意,顺便说一句,我完全理解* that *视角的观点。虽然我不明白投票“关闭”!这是一个通用的问题,但不容易通过阅读文档来回答 - 我使用的代码在这里,因为不使用代码很难解释。 – username 2012-08-12 04:47:57

+0

我不能说谁投票决定关闭它,但它看起来像是一个写得很好的建设性问题,所以我只是假设某人心情不好,并且没有仔细阅读这个问题或仔细阅读这个问题帮助改善它。 ;-) – Jordan 2012-08-12 05:04:52

+0

废话,现在因为我的抱怨而上升。停下来! Downvotes很好,可能是有保证的,请不要关闭它 – username 2012-08-12 05:07:45

回答

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而不会产生不必要的混乱的简单方法)。

+0

这很有帮助。我发现“class assignment”错误在python.or上也被描述为“对象布局不同”,因此我将尝试更改我的“密封”方法以删除与目标Class不同的任何成员/方法。如果它有效,如果创建第二个实例的时候我并没有真正看到我的程序抛出错误的缺点,当我仅仅创建一个实例时 - 如果有的话,它是免费的更严格的错误检查,不是?此外,“状态设计”链接很有帮助 - 我需要更仔细地阅读它 – username 2012-08-12 06:53:57

+0

更正:如果创建第二个*引用* – username 2012-08-12 07:17:26

2

不,你不能有一个变量值通过调用它的方法取代自己。正常的做法是这样的:e = e.getSealedValue()

你可以做一个对象改变的行为,但这通常被认为是一个坏主意,并可能导致高度不可维护的代码。

+1

1.你可以通过调用它的方法来完全改变一个对象的行为(尽管这是一个坏主意)2.'e = ..'不能代替对象。它将名称“e”绑定到另一个对象。 – jfs 2012-08-12 05:24:31

2

即使有一些理智的方式,使其工作,我会避免走这条路,只是因为它改变了对象的类型的东西与现有的合同完全不符。

现在,人们可以说“但我只在一个地方使用它,其他代码路径永远不会看到旧的合同”,但不幸的是,这不是这个机制的一个参数,因为你只能简单地一旦拥有最终对象,就可以为其他代码路径提供该值。

总之,不要这样做,甚至不要尝试。