Monkey补丁可以替换类中现有的函数定义吗?

2024-10-02 00:20:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道SO社区有多激烈,所以我会尽我所能保留这个问题minimal, complete and verifiable。在

我只想知道monkey patching是否可以用来代替现有函数的定义?在

例如:

class A():

    def foo():
       print '2'

def foo():
    print '5'

A.foo = foo

这种方式似乎也不起作用,为什么我不只是添加一个新函数而不是替换一个现有函数,我在其他类中调用这些函数,我的理解是monkey patching在运行时添加了这些函数,我需要我的python代码在apachespark服务器上运行,这会抛出一个错误,认为对该函数的调用未被引用。在

所以请友好点,帮我解决问题或者建议一个解决办法。 谢谢。在

编辑:代码的目标是在调用A.foo时打印5。在


Tags: and函数代码so定义foodef社区
2条回答

您唯一的问题是您没有正确定义foo。它需要为调用它的实例提供一个显式参数。在

class A(object):
    def __init__(self)
        self.x = 2

    def foo(self):
        print(self.x)

def foo(this):
    print(this.x + 3)

A.foo = foo

a = A()
a.foo()  # outputs 5 in Python 2 and Python 3

从一个非常真实的意义上讲,monkey-patching首先就是类的创建方式。class语句几乎只是以下代码的语法糖分:

^{pr2}$

type的定义想象成类似于

def type(name, bases, d):
    new_class = magic_function_to_make_a_class()
    new_class.name = name
    new_class.bases = bases
    for k, v in d.items():
        setattr(new_class, k, v)
    return new_class

我希望我能理解你在这里想做什么。这在python3中是可行的:

class A():

  def foo():
     print('2')

def foo():
  A.foo = lambda: print('5')

A.foo() # Print '2'
foo()   # Assign the new method
A.foo() # Prints '5'

但是在python2中有几个注意事项。在

所以你必须这样做:

^{pr2}$

编辑: 在看到你在评论中的问题后,我想你其实想要一些不同的东西。这是:

class A():

    def foo(self):
       print '2'

def foo(self):
  print '5'

a = A()
a.foo() # Print '2'
A.foo = foo   # Assign the new method
a.foo() # Prints '5'

这在python2中工作得很好。在

self是对方法绑定到的当前实例的引用。当您只是调用诸如print之类的访问附加到该实例的任何属性或方法的东西时,不使用它。但对于不同的情况,请看以下示例:

class A():

    msg = "Some message"

    def foo(self):
       print self.msg


def bar(self):
  self.msg = "Some other message"

a = A()
a.foo() # Print old msg
A.bar = bar   # Assign the new method
a.bar() # Assigns new message
a.foo() # Prints new message

同样正如切普纳在其帖子下的评论中指出的:

The name self isn't special; it's just a convention. You could use this if you really wanted to, and it doesn't need to be the same name in both functions defined here. What is important is that the first argument to a function used as an instance method will be a reference to the calling object. a.foo() is almost exactly the same as A.foo(a)

相关问题 更多 >

    热门问题