我的python代码中有类似的东西
class A:
__mess = "Yeap!"
def doSome(self):
self.FN()
def FN(self):
pass
def myFN(self):
print self.__mess
b = A()
b.FN = myFN
b.doSome()
但这不起作用。我哪里错了?
python 2.6.5
upd:我想仅为一个示例(b)重新定义方法(FN)。
UPD2:
import new
class A:
__mess = "Yeap!"
def doSome(self):
self.FN()
def FN(self):
pass
def myFN(self):
print self.__mess
b = A()
b.FN = new.instancemethod(myFN, b, A)
b.doSome()
也行不通。
追踪(最近的呼叫最后):
文件“”,第1行,在中 doSome中的文件“”,第4行 myFN中的文件“”,第2行 AttributeError:实例没有 属性'__mess'
答案 0 :(得分:4)
myLoopFN
是一个函数,而不是实例方法。做
import new
b.loopFN = new.instancemethod( myLoopFN, b, A )
问题在于Python将实例方法与常规函数略有不同:它们将运行它们的实例作为默认的第一个参数。如果在类定义中定义一个方法,它会自动成为一个实例方法,这样当你实例化它时,它就会传递实例。但是,当您定义myLoopFN
时,在之外的类定义中,因此它是普通函数而不是实例方法。您可以通过将其明确声明为实例方法来解决此问题。
...
这很icky因为不是你应该做的事;在运行时更改实例方法将导致问题。您永远不会确定您的A
是原始A
还是已修改的loopFN
,并且您将无法调试它,因为您无法判断您是否已更改{{1} }} 或不。这会给你Nyarlathotep自己会引以为豪的那种错误。
执行此操作的正确方法是子类A
并覆盖该方法,以便您可以区分不同的类。
class myA( A ):
def loopFN(self):
#put modified function here
这样,您可以实例化修改后的类并确定其方法。
您使用的是双下划线变量名称__mess
。你(几乎可以肯定)不想这样做。由于某些原因,只有我们的仁慈独裁生活和其他少数人知道,Python会自动将这些__
名称变为_<class-name>__
,作为一种虚假的私有变量。这太可怕了,除此之外没有理由称之为__mess
而不是(更好)mess
。
如果您绝对必须将其称为__mess
,您可以按以下方式参考:
def myFN(self):
print( self._A__mess )
(当您更改A的名称时,经过必要的修改)。这是令人讨厌和unPythonic。
答案 1 :(得分:1)
关于第二个错误(使用__mess
):
更改
print self.__mess
到
print self._mess
并改变
class A:
__mess = "Yeap!"
到
class A:
_mess = "Yeap!"
双下划线告诉Python使用name-mangling。
另一种方法是改变
def myFN(self):
print self.__mess
到
def myFN(self):
print self._A__mess