python如何在运行时更改方法的功能

时间:2010-12-10 10:31:08

标签: python

想知道在运行期间是否可以更改方法的功能化,例如

x = obj1 + obj2
return x+y

并且您要添加

x = obj1 + obj2
x+= obj3
return x+y

5 个答案:

答案 0 :(得分:14)

在python类中,只是在运行时可以可以更改的对象。例如:

class Dog:
    def talk(self):
        print "bark"
dog1 = Dog()
dog1.talk()  # --> Bark

def cat_talk(self):
    print "Meow"

Dog.talk = cat_talk
dog1.talk()  # --> Meow

但你不希望做这样的事情,或者那些必须维护或调试此程序的人肯定会试图杀死你(而这个人可能就是你自己)

答案 1 :(得分:2)

一切皆有可能,你可以在运行时进行堆栈操作和插入字节码。查看byteplay等内容。

但为什么??

此类修改不直观且不可读,最好先将x += obj3放在首位,并将obj3设置为0;当您需要该行来执行某些操作时,您在obj3 ...

上使用非零值

答案 2 :(得分:1)

在运行时更改方法的功能是程序始终执行的操作。它被称为“概括。”

您所做的只是编写更通用的算法。这并不难。

def run_time_change( y, *object_list ):
    x=sum( object_list )
    return x+y

example1 = run_time_change(y, obj1, obj2 )
example2 = run_time_change(y, obj1, obj2, obj3 )

没有“运行时”代码更改的地方。那是错的。

正确的做法是编写更通用的算法。

答案 3 :(得分:1)

(据我所知) 有一些但有限的方法可以让某人实现你想要的...... 主要由短语“Monkey Patching”来描述 (这里也有其他人提到过)或者当一般谈到代码操作和/或在运行时执行,通常也称为“动态/运行时代码执行” [...]

⚠️只是一种方法!

我将以自己的方式与您分享一种我认为非常简单和有趣的方法,尤其是在涉及脚本 (或那些“最终成为”/编译-到中间 [例如 VB.NET 到 MSIL]) 语言 [...] 就像在 python 中一样,你可以按照以下几行做一些事情,或者干脆< strong>以下行:

oldCode = '''
global x
x = objs[0] + objs[1]
'''

newCode = '''
global x
x = objs[0] + objs[1]
x += obj3 # <-- Notice here 
x += y
'''

class Ego:
   def doMethod(self, objs=None,y=1):
       exec(oldCode)
       return x

      
I = Ego()

obj1 = 8
obj2 = 2
obj3 = 1

print('Before:', I.doMethod([obj1,obj2]))
oldCode = newCode #Swiching to new-Code
print('After :', I.doMethod([obj1,obj2]))

输出:

Before: 10
After : 12

⚠️ 免责声明这不是对所有用例的推荐,而只是一种方法(请不要因此讨厌我。) ⚠️

尾声

请记住,这不是我推荐任何人使用的方式(出于多种原因[...]),而只是证明概念,因为它确实是一种可以完成的方式,所以我想“为什么不分享它?”......给你! 玩得开心!:P

答案 4 :(得分:0)

目前还不完全清楚你想做什么,但是changing methods and classes at runtime is called "Monkey Patching",并且在Python中不赞成(顾名思义)。

原因是因为它使您的代码非常难以调试,因为只需通过读取代码调用哪个版本的方法就可以轻松判断。或者更有可能的是,执行调试的人甚至不会意识到方法已被改变,因此可以理解他们所看到的所有行为。

因此,虽然您可以动态更改方法,但最好不要这样做。如果您提供有关您尝试解决的问题的更多详细信息,则可以建议更多“Pythonic”解决方案。