在Python中为运行时的对象分配方法

2024-05-08 00:05:05 发布

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

我正在尝试用Python实现Javascript的等效功能:

a.new_func = function(arg1, arg2) {
    var diff = arg1 - arg2;
    return diff * diff;
}

现在,我做这件事的方式是先定义方法,然后赋值,但我的问题是Python是否允许速记在同一行中完成赋值和定义部分。像这样:

a.new_func = def new_func(arg1, arg2):
    diff = arg1 - arg2
    return diff * diff

而不是这样:

def new_func(arg1, arg2):
    diff = arg1 - arg2
    return diff * diff
a.new_func = new_func

我意识到区别并不大,但我仍然有兴趣知道这是否可能。你知道吗


Tags: 功能newreturnvardef方式difffunction
3条回答

Python不支持这种语法。你知道吗

我想如果你愿意,你可以写一个装饰师。它可能看起来更好一点:

def method_of(instance):
    def method_adder(function):
        setattr(instance, function.__name__, function)
        return function
    return method_adder

@method_of(a)
def new_func(arg1, arg2):
    stuff()

或者,如果希望该方法能够访问self

def method_of(instance):
    def method_adder(function):
        setattr(instance, function.__name__, function.__get__(instance))
        return function
    return method_adder

@method_of(a)
def new_func(self, arg1, arg2):
    stuff()

您应该注意到实例方法不是lambda。你知道吗

例如,让我们在IPython中做一个简单的实验

In [12]: class A:
   ....:     def f(self):
   ....:         return 1
   ....:     

In [13]: A.f.__class__
Out[13]: instancemethod

In [14]: another_f = lambda self: 1

In [15]: another_f.__class__
Out[15]: function

试图将属性绑定到lambda会在调用它时失败。你知道吗

In [27]: an_instance = A()

In [28]: an_instance.g = lambda self: 2

In [29]: an_instance.g()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-29-5122c91d3e8f> in <module>()
----> 1 an_instance.g()

TypeError: <lambda>() takes exactly 1 argument (0 given)

相反,您应该做的是用types.MethodType包装lambda

In [31]: an_instance.g = types.MethodType(lambda self: 2, an_instance)

In [32]: an_instance.g()
Out[32]: 2

descriptors背后发生了一些奇怪的魔法。在我看来,这不是一个很好的解决方案,但是。。。如果你想了解更多,这里有一个链接http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html

最接近您要查找的是lambda表达式,它不像正确编写的函数那样易于使用:

a.new_function = lambda arg1,arg2 : (arg1-arg2)**2

然而,在几乎所有的情况下,定义一个函数,并分配它,你在你的例子中所做的方式是正确的

相关问题 更多 >