我有一个用于制作匿名课程的课程:
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
推到那里......
有人知道如何实现这一目标吗?
答案 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