如何以编程方式设置python实例方法

时间:2017-10-10 16:12:17

标签: python

我有一个用于制作匿名课程的课程:

class Anonyclass(object):
    def __init__(self, **kwargs):
        for kwarg in kwargs:
            self.__setattr__(kwarg, kwargs[kwarg])

它非常适合动态设置属性,但我无法以这种方式设置实例方法,因为它们无法访问self。例如Anonyclass(foo = lambda x: x**2).foo(5) == 25,但我似乎无法将self推到那里......

有人知道如何实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

这不是创造新的"类"只是Anonyclass的实例。 就像您可以设置实例属性一样,您可以设置可调用属性,这些属性知道它们绑定到哪个实例。

因此,假设任何可调用的参数作为参数传递,将self作为第一个参数,您可以将代码更改为:

from functools import partial

class Anonyclass(object):
    def __init__(self, **kwargs):
        for kwarg, attr in kwargs.items():
            if callable(attr):
                  attr = partial(attr, self)
            setattr(self, kwarg, attr)

这是必需的,因为实例中设置的可调用功能会绕过mechanism Python uses to bind a method to an instance自动添加" self"所有电话的参数。所以我们使用functools.partial来做同样的事情。 (可以用lambdas完成,但是我们需要两个级别的lambda,以便" attr"变量能够保持自己与正确方法绑定,而不是指向最后一个for循环中分配的元素

此外,如果您想要实际创建而不是绑定属性的实例,您可以只调用type,并传递与kwargs相同的参数。你的代码:

def anon_class_factory(**kwargs):
   return type("Anonyclass", (object,), kwargs)

这将使kwargs中传递的任何函数表现为"真实"方法

答案 1 :(得分:1)

你可以像下面这样做。您可能必须修改for kwarg, value in kwargs.items():循环以检查分配的值类型,并以不同方式处理属性的数据和/或属性类型。我没有尝试其他任何事情,因为你的问题中没有任何例子。

class _Callable(object):
    def __init__(self, instance, name, value):
        self.name = name
        self.instance = instance
        self.__setattr__(name, value)

    def __call__(self, *args):
        return self.__dict__[self.name](self.instance, *args)

class AnonyClass(object):
    def __init__(self, **kwargs):
        for kwarg, value in kwargs.items():
            setattr(self, kwarg, _Callable(self, kwarg, value))

value = 6.480740698407860230965967436088
print( AnonyClass(foo=lambda self, x: x**2).foo(value) )  # -> 42.0