繁体   English   中英

将函数用作具有Enthought特性的实例方法(Python)

[英]Using function as an instance method with Enthought Traits (Python)

我想创建一个基于函数的实例方法,作为实例初始化的参数,如下所示:

from traits.api import *

class C(HasTraits):
    f = Function

c = C(f=lambda self: self)

但是,如果我跑步

c.f()

它说(毫不奇怪)

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

将f从Function更改为Method并没有帮助,因为它不接受function参数(需要instancemethod)。

所以我的问题是,如何在使用Traits时让自定义函数充当实例方法(将self参数用作普通实例方法)?

一个函数(无论是用lambda还是def定义的)都不是方法。

您不能只更改其类型; 方法比函数具有更多的信息-它与对象绑定。 这就是Python知道第一个( self )参数传递什么的方式。

在您的情况下,您正在寻找未绑定方法 ,该方法未绑定到对象,但仍绑定到

在正常情况下(当你def一个内部的方法class的定义,然后创建类的实例,然后调用一个方法就可以了),这为您自动发生。 (有关更多详细信息,请参见方法的工作原理 。)但是,当您自己完成所有操作时,您需要自己创建绑定方法。

与Python中的其他任何类型一样,您可以通过将该类型称为构造函数来实现。 问题是“绑定方法”不能作为内置类型访问。 这意味着您必须转到types模块,该模块“为标准Python解释器使用的某些对象类型定义名称”。 像这样:

bound = types.MethodType(func, my_obj, type(my_obj))

unbound = types.UnboundMethodType(func, None, my_type)

但是请注意,通常没有充分的理由执行此操作-您可以轻松地将对象塞入闭包中。 这些可调用对象都将执行相同的操作:

func = lambda self: self
bound = types.MethodType(func, my_obj, type(my_obj))

func2 = lambda: my_obj

func3 = lambda self: self
unbound = types.UnboundMethodType(func, None, my_type)
func3a = lambda: unbound(my_obj)    

最后两个想法:

如果您了解描述符 ,那么使@property起作用的魔力和使绑定方法起作用的魔力将相互干扰。 我不知道Enthough特质是否正确,但事实可能如此。 因此,您的问题的答案很可能是“您无法做到”。 取而代之的是,您将必须先创建一个Function特征,然后创建一个包装器方法,以显式调用该特征。

如果使用Python 3.x而不是2.x,则未绑定的方法会消失(类仅使用简单的旧函数),因此您遇到的许多复杂性都不会出现。

如下定义新的Trait类型MyMethod:

import types
class MyMethod(TraitType):
    def validate(self, object, name, value): 
        if isinstance(value, types.MethodType):
            return value
        if isinstance(value, types.FunctionType):
            return types.MethodType(value, object, object.__class__)
        self.error(object, name, value)

并使用它代替之前的代码中的Function或Method,函数将自动转换为实例方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM