我怎样才能得到链接在 class 中的方法的名称?

How can i get the names of the methods that were chained in a class?

考虑以下代码示例,它显示了一个简单的 class,它允许通过返回 self 进行方法链接。

import inspect

class classname(object):
    def __init__(self):
        self.hold = None

    def funcname(self):
        self.hold = 'a'
        return self

    def method(self, c):
        self.hold = self.hold * c
        return self


c = classname().funcname().method(10)

我想做的是以某种方式检查 c,这样我就可以看到 funcnamemethod 是在 class 上被调用的。

可以做到,但不能通过 inspect,因为实例本身不记得那段历史。您必须添加代码以手动维护调用。

class classname(object):
    def __init__(self):
        self.hold = None
        self.calls = []

    def funcname(self):
        self.hold = 'a'
        return self

    def method(self, c):
        self.hold = self.hold * c
        return self

    def __getattribute__(self, name):
        self_calls = object.__getattribute__(self, "__dict__")["calls"]
        self_calls.append(name)
        return object.__getattribute__(self, name)


c = classname().funcname().method(10)
print(c.calls)

我已经为这类事情写了 a library,我只是把它放在 GitHub 以防它对任何人有用。

它通过包装函数、类 或带有记录每次交互的代理的对象来工作。这不仅包括方法的名称,还包括它们的参数和 return 值,以及哪些方法调用了哪些其他方法(在树中)。

用法:

from tracer import tracer

@tracer
class classname(object):
    def __init__(self):
        self.hold = None

    def funcname(self):
        self.hold = 'a'
        return self

    def method(self, c):
        self.hold = self.hold * c
        return self

    def recursive_method(self, n):
        if n > 0:
            self.recursive_method(n - 1)
            self.recursive_method(n - 2)

c = classname().funcname().method(10)
c.recursive_method(3)

c.print_call_tree()

输出:

* +-> __init__()
  |
  +-> funcname() +-> <__main__.classname object at 0x0000000002A9EBA8>
  |
  +-> method(10) +-> <__main__.classname object at 0x0000000002AE2160>
  |
  +-> recursive_method(3) +-> recursive_method(2) +-> recursive_method(1) +-> recursive_method(0)
                          |                       |                       |
                          |                       |                       +-> recursive_method(-1)
                          |                       |
                          |                       +-> recursive_method(0)
                          |
                          +-> recursive_method(1) +-> recursive_method(0)
                                                  |
                                                  +-> recursive_method(-1)

公平警告:它有点脆弱,例如,您可以看到日志显示由 funcnamemethod 编辑的对象 return 的不同 ID,即使这些应该是具有相同 ID 的相同对象。