[英]How to pass a callable to a class so that it can access instance attributes in Python?
Suppose I have this class:假设我有这个 class:
class ClassA:
def __init__(self, callable):
self.name = "Hey!"
self.callable = callable
def call(self):
self.callable()
And I want to pass into callable
a function that can access name
:我想将一个可以访问
name
的 function 传递给callable
的:
def function_a():
print(f"{self.name}")
So that this所以这
a = ClassA(function_a)
a.call()
Yields this:产生这个:
Hey!
How should I go about this?我应该如何 go 关于这个? Metaclassing?
元分类? Class decoration?
Class 装饰? Or should I just overhaul my architecture so that I don't need to do such a thing?
还是我应该彻底检查我的架构,这样我就不需要做这样的事情了?
Edit with a more clear example使用更清晰的示例进行编辑
The former example seems like I'm just trying to access that attribute, this is not the case.前一个示例似乎我只是想访问该属性,事实并非如此。 In a more sophisticated demo, consider this:
在更复杂的演示中,考虑一下:
class ClassA:
def __init__(self, selection):
self.numbers = [randint(1, 100) for _ in range(10)]
self.selection = selection
def select(self):
return self.selection(self.numbers)
And then suppose I want the caller to be able to provide different strategies for selecting those numbers, like然后假设我希望呼叫者能够提供不同的策略来选择这些号码,比如
a = ClassA(selection_strategy)
a.select()
In that architecture, selection_strategy
is a callable defined outside of the class that needs to somehow have access to that object attributes.在该架构中,
selection_strategy
是在 class 之外定义的可调用对象,需要以某种方式访问该 object 属性。
Aaaaand just as I was writing this, I realized that what I want is actually really simple, I just have to make selection_strategy
accept the arguments I want from the class and call it within select
.啊啊啊,就在我写这篇文章的时候,我意识到我想要的实际上非常简单,我只需要让
selection_strategy
接受我想要的 arguments 从 class 中调用它并在select
中调用它。 I'm sorry, SO, I've been working for a few hours and this totally slipped by me.对不起,我已经工作了几个小时,这完全被我忽略了。
Thanks!谢谢!
I wonder if this is of any real use, but you could use我想知道这是否有任何实际用途,但你可以使用
...
def call(self):
self.callable(self)
def function_a(cls):
print(f"{cls.name}")
a = ClassA(function_a)
a.call()
# Hey!
this seems like a terrible idea but here you go这似乎是一个糟糕的主意,但在这里你 go
>>> def hello():
... print 'hello: '+name
...
>>> hello()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in hello
NameError: global name 'name' is not defined
>>> exec hello.func_code in {'name':'bob'}
hello: bob
>>>
Since it is not clear what the point of any of this is, it is hard to know what answer will work.由于尚不清楚这有什么意义,因此很难知道哪种答案会奏效。 However, other than the obvious idea of the "callable" taking an argument, the simplest thing is to define a callable class
然而,除了“可调用”带参数的明显想法之外,最简单的事情是定义一个可调用 class
Class callable(object):
def __init__(self, otherclass):
self.name = otherclass.name
def _call__(self):
print(self.name)
then instantiate this with然后实例化它
foo = callable(ClassAInstance)
The callable can't officially be a method because methods must be defined on the class object itself.可调用对象不能正式成为方法,因为方法必须在 class object 本身上定义。 But does it really have to be a method?
但它真的必须是一种方法吗? You could just define the callable as a regular function taking a single parameter that just happens to be an instance object's
self
reference.您可以将可调用对象定义为常规的 function ,采用恰好是实例对象的
self
引用的单个参数。 Namespace resolution is different - you can't use class level variables - but if that's not a problem, this will work:命名空间解析不同 - 您不能使用 class 级别变量 - 但如果这不是问题,这将起作用:
class ClassA:
def __init__(self, callable):
self.name = "Hey!"
self.callable = callable
def call(self):
self.callable(self)
def function_a(self):
print(f"{self.name}")
a = ClassA(function_a)
a.call()
If you want the function to be able to use self, you must make it a method, like this:如果您希望 function 能够使用 self,则必须将其设为方法,如下所示:
class ClassA:
def __init__(self):
self.name = "Hey!"
self.callable = self.function_a
def call(self):
self.callable()
def function_a(self):
print(f"{self.name}")
Or, you can pass the name as a parameter:或者,您可以将名称作为参数传递:
class ClassA:
def __init__(self):
self.name = "Hey!"
self.callable = self.function_a
def call(self):
self.callable(self.name)
def function_a(name):
print(f"{name}")
a = ClassA(function_a)
a.call()
Hope this helps!希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.