简体   繁体   English

如何判断何时调用另一个类中的函数

[英]How to tell when a function in another class has been called

I have two Python classes, call them "C1" and "C2". 我有两个Python类,称它们为“C1”和“C2”。 Inside C1 is a function named "F1" and inside C2 is a function named "F2". C1内部是名为“F1”的函数,C2内部是名为“F2”的函数。 Is there a way to execute F2 each time F1 is run without making a direct call to F2 from within F1? 有没有办法在每次F1运行时执行F2而不从F1内直接调用F2? Is there some other mechanism by which to know when a function from inside another class has been called? 是否有其他机制可以知道何时调用另一个类中的函数?

I welcome any suggestions, but would like to know of some way to achieve this without making an instance of C2 inside C1. 我欢迎任何建议,但想知道实现这一目标的一些方法,而不在C1中创建C2的实例。

You can write a little helper decorator that will make the call for you. 你可以写一个小助手装饰器来为你打电话。 The advantage is that it's easy to tell who is going to call what by looking at the code. 优点是通过查看代码可以很容易地判断谁将调用什么。 And you can add as many function calls as you want. 您可以根据需要添加任意数量的函数调用。 It works like registering a callback function: 它就像注册回调函数一样:

from functools import wraps

def oncall(call):
    def helper(fun):
        @wraps(fun)
        def wrapper(*args, **kwargs):
            result = fun(*args, **kwargs)
            call()
            return result
        return wrapper
    return helper

class c1:
   @classmethod
   def f1(cls):
      print 'f1'

class c2:
   @classmethod
   @oncall(c1.f1)
   def f2(cls):
      print 'f2'

>>> c2.f2()
f2
f1
>>> c1.f1()
f1

I believe that what you are trying to do would fit into the realm of Aspect Oriented Programming . 我相信你想要做的事情将适合面向方面编程的领域。 However I have never used this methodology and don't even know if it can/has been implemented in Python. 但是,我从未使用过这种方法,甚至不知道它是否可以/已经在Python中实现。

Edit I just took a look at the link I provided and saw that there are 8 Python implementations mentioned. 编辑我刚刚看了一下我提供的链接,发现有8个Python实现提到了。 So the hard work has already been done for you :-) 所以已经为你做了很多努力:-)

You can do aspect-oriented programming with function and method decorators since Python 2.2: 从Python 2.2开始,您可以使用函数和方法装饰器进行面向方面的编程:

@decorator(decorator_args)
def functionToBeDecorated(function_args) :
    pass

It really depends on why you don't want to call F2 directly from within F1. 这实际上取决于你不想直接从F1中调用F2的原因。 You could always create a third class (C3) which encapsulates both C1 and C2. 你总是可以创建一个封装C1和C2的第三类(C3)。 When F3 is called, it will call both F1 and F2. 当调用F3时,它将同时调用F1和F2。 This is known as the Mediator pattern - http://en.wikipedia.org/wiki/Mediator_pattern 这被称为Mediator模式 - http://en.wikipedia.org/wiki/Mediator_pattern

Not knowing what is you are trying to achieve, i would suggest taking a look at pydispatcher. 不知道你想要达到的是什么,我建议看看pydispatcher。 It allows you to implement the Observer pattern 它允许您实现Observer模式

Basically, you register F2 with the dispatcher so that it will be called when a specific 'signal' is emitted. 基本上,您将F2与调度程序一起注册,以便在发出特定“信号”时调用它。 Your F1 'emits a signal' that says "I've been called". 你的F1'会发出一个信号,上面写着“我被称为”。 The dispatcher then calls F2 (or any number of functions that have registered themselves with that particular signal). 然后,调度员调用F2(或任何已经使用该特定信号注册的功能)。 Its actually really simpler than it sounds, easy to use, and de-couples your code (F1 does not need to know about F2). 它实际上比它听起来更简单,易于使用,并且解耦你的代码(F1不需要知道F2)。

(arhh.. I'm a new user and not allowed to include hyperlinks, but pydispatcher is easy to google for) (arhh ..我是新用户,不允许包含超链接,但pydispatcher很容易google for)

You catch all accesses to F1 with __getattr__ . 您可以使用__getattr__捕获对F1的所有访问。 This will allow you to do extra processing or return your own function in place of F1 这将允许您进行额外处理或返回自己的功能代替F1

class C1:
  def __getattr__(self,name):
    if name == 'F1': C2.F2()
    return self[name]

I should warn you that this will call C2.F2 even if F1 is only being accessed (not run). 我应该警告你,即使只是访问F1(不运行),这也会调用C2.F2。 It's rare but not impossible that F1 might simply be accessed for another purpose like f = myC1.F1 . 很少但并非不可能简单地将F1用于其他目的,例如f = myC1.F1 To run F2 only on a call of F1 you need to expand this example to combine F2 with the returned function object. 要仅在F1调用时运行F2,您需要展开此示例以将F2与返回的函数对象组合。 in other words: 换一种说法:

def F1F2():
   self.F1()
   C2.F2()
return F1F2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保在第一次调用另一个类函数之前不会调用类函数? - How to make sure a class function wont be called until another class function has been called first? 如何判断是否已在Python中调用过函数? - How do I tell whether a function has been called in Python? 当另一个类方法被调用时,如何导致类方法的执行 - How to cause execution of a class method when ever another class method has been called 一个函数可以知道它是如何被调用的吗? - Can a function know how it has been called? 如何以编程方式告诉 AWS Step Function 执行已完成? - How to tell programmatically that an AWS Step Function execution has been completed? 调用不同的函数后如何保持函数运行? - How to keep a function going after different function has been called? 如何检查一个方法是否已调用另一个方法? - How to check in one method if another method has been called? 如何测试一个函数被调用了多少次 - How to test how many times a function has been called 如何在Python中放入“如果函数已被多次调用”? - How to put “if the function has been called this many times” in Python? Python:如何等到 function 在不同的线程中被调用? - Python: How to wait until a function has been called in a different thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM