以下程序无法创建类
的功能class MyClass(object):
def __init__(self, name=""):
self.name = name
def read_name(self):
return self.name
# First argument should be a ref to class
def callback(fcn, arg):
fcn.name=arg
# Create a instance of class
a = MyClass("Blue")
# Lets add new member functions
setattr(a, 'callback1', callback)
setattr(a, 'callback2', callback)
print a.read_name()
print a.callback1("purple") #! FAILS
print a.callback2("cyan") #! FAILS
自动创建类成员函数的正确方法是什么?
我想创建N' N'回调函数,它们都会修改一些常见/不常见的类数据(共享字典)
编辑1
我希望收集N' N'通过传递回调函数来分离/并行线程。我事先不知道我需要多少个回调函数,因此我想在飞行中创建它们。
编辑2
我有一个字典(d),我存储不同进程的信息。在回调中访问字典(d)。但是因为在不同的线程上调用相同的callback
函数,所以字典数据会出现乱码。作为一个quickfix,我想到了创建单独的回调。
答案 0 :(得分:3)
如果您知道自己在做什么,就想尝试
import types
setattr(a, 'callback1', types.MethodType(callback, a, MyClass))
答案 1 :(得分:1)
您无法向实例添加类方法;你必须把它添加到班级:
setattr(MyClass, 'callback1', callback)
但这仍然是一个糟糕的主意。你为什么想要这个功能?
编辑:改为将回调放在容器中:
class MyClass(object):
def __init__(self, name=""):
self.name = name
self.callbacks = []
def callback(self, idx, arg):
self.callbacks[idx](self, arg)
# First argument should be a ref to class
def callback(fcn, arg):
fcn.name=arg
# Create a instance of class
a = MyClass("Blue")
# Lets add new member functions
a.callbacks.append(callback)
a.callbacks.append(callback)
print a.name
a.callback(0, "purple")
print a.name
a.callback(1, "cyan")
print a.name
答案 2 :(得分:1)
简而言之:在移植方法时,将其分配给类,而不是实例。
这是一个清晰的例子。
class A(object):
"""As trivial as a class can get."""
def foo(self):
return self.bar(1) + self.baz()
# Rework everything!
def new_bar(self, x):
return 'I got %r' % x
def new_baz(self):
return ' and I\'m okay!'
A.bar = new_bar
A.baz = new_baz
print A().foo()
现在将方法移植到实例。
a = A()
# An instance attribute is a bound method;
# when we replace it with a function, we lose access to self.
a.bar = lambda x: x * 100
A.baz = lambda self: 42
assert a.foo() == 142
# We can do better, though.
from types import MethodType
a2 = A()
a2.foo = MethodType(lambda self: 'I know myself, my class is %s' % self.__class__.__name__, a2)
print a2.foo()
请注意,您不需要setattr
来设置属性,甚至是未知属性。您可能还记得,setattr
中也没有使用__init__
。