关于元编程:python独立函数返回调用它的对象实例

python standalone function return object instance that called it

我有一个非常奇怪的问题。

我需要返回一个类对象来调用一个应该返回调用它的类对象的函数。 我知道我知道。 只是把它想象成一个人为的练习,虽然对我来说这是一个非常现实的需要。

1
2
3
4
5
6
7
8
9
def baz():
    # return the object instance that calls me.

class Foo():
    def bar(self, func):
        return func()  # should return the Foo object but how???

new_foo = Foo()
new_foo_instance = new_foo.bar(baz)

是否有可能在baz()中写入任何会返回调用它的对象?

编辑:

回答评论:

我曾尝试使用inspect,但没有成功,我甚至查看了整个堆栈,但我找不到与new_foo对象匹配的条目:

当我打印出来时,new_foo看起来像这样:<__main__.Foo object at 0x0000029AAFC4C780>

当我打印出整个堆栈时,在其中找不到该条目:

1
2
3
4
5
6
7
8
def baz():
    print(inspect.stack())
    return inspect.stack() #[1][3]

>>> [FrameInfo(frame=<frame object at 0x0000029AADB49648>, filename='return_caller.py', lineno=5, function='baz', code_context=['    print(inspect.stack())
'
], index=0), FrameInfo(frame=<frame object at 0x0000029AAD8F0DE8>, filename='return_caller.py', lineno=11, function='bar', code_context=['        return func()  # should return the Foo object but how???
'
], index=0), FrameInfo(frame=<frame object at 0x0000029AAD8AC588>, filename='return_caller.py', lineno=19, function='<module>', code_context=['new_foo_instance = new_foo.bar(baz)
'
], index=0)]

所以我不是试图让它返回Foo的新实例,而是实际上与new_foo完全相同的实例。


使用检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import inspect

def baz():
    frame_infos = inspect.stack()  # A list of FrameInfo.
    frame = frame_infos[1].frame   # The frame of the caller.
    locs = frame.f_locals          # The caller's locals dict.
    return locs['self']

class Foo():
    def bar(self, func):
        return func()

f1 = Foo()
f2 = f1.bar(baz)
print(f1)
print(f2)
print(f2 is f1)  # True

或作弊:

1
2
3
4
5
6
7
def baz():
    return getattr(baz, 'self', None)

class Foo():
    def bar(self, func):
        func.self = self  # Functions can be a place to store global information.
        return func()

以上答案是完美的,这是满足您需求的另一种方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import sys
import inspect

def baz():
   """
    Return the object instance whose method calls me
   """

    for item in dir(sys.modules[__name__]):
        elem = eval(item)

        if inspect.isclass(elem):
            foo_instance = elem()
            break

    return foo_instance

class Foo():
   """
    Foo class
   """

    def bar(self, func):
        return func()  # should return the Foo object but how???

# Instantiation and calling
new_foo = Foo()
new_foo_instance = new_foo.bar(baz)

print(new_foo_instance)       # <__main__.Foo object at 0x0000015C5A2F59E8>
print(type(new_foo_instance)) # <class '__main__.Fo


# E:\Users
ishikesh\Projects\Python3\try>python Get_caller_object_final.py
# <__main__.Foo object at 0x0000015C5A2F59E8>
# <class '__main__.Foo'>

参考&raquo;

  • 如何在Python中获取当前模块中所有类的列表?
  • Python:只使用dir()获取导入模块中定义的类?