简体   繁体   English

如何将可调用对象传递给 class 以便它可以访问 Python 中的实例属性?

[英]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.

相关问题 如何将 class 的实例传递到其构造函数中的属性中,并让这些属性访问初始化的属性? - How to pass an instance of a class into attributes within its constructor and have those attributes access initialized attributes? 如何装饰可调用类的实例? - How can I decorate an instance of a callable class? 我怎样才能干净地将 class 属性分配为 Python 中的 class 的实例? - How can I cleanly assign class attributes as an instance of that class in Python? 在python中访问类实例属性的最佳方法 - Best ways to access class instance attributes in python 是否可以在python的类中单独访问实例属性? - Is it possible to access instance attributes separately in a class in python? 我如何找出 python class 中的哪些属性是可调用的? - How do i find out what attributes in a python class are callable? python:类属性和实例属性 - python: class attributes and instance attributes 如何在unittest Python中创建继承的类的实例,以便我可以在simpleXMLRPCServer中注册该类的实例 - How to create an instance of an inherited class in unittest Python so that I can register the instance of that class in simpleXMLRPCServer python 范围 class 实例属性如何只读? - How are the python range class instance attributes readonly? 如何更改实例属性 python class - How to change instance attributes in python class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM