【问题标题】:python standalone function return object instance that called itpython独立函数返回调用它的对象实例
【发布时间】:2019-04-13 16:25:56
【问题描述】:

我有一个很奇怪的问题。

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

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() 中编写任何返回调用它的对象的内容?

编辑:

回答cmets:

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

new_foo 打印出来时是这样的:<__main__.Foo object at 0x0000029AAFC4C780>

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

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())\n'], 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???\n'], 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)\n'], index=0)]

所以我不想让它返回Foo 的新实例,但实际上与new_foo 完全相同。

【问题讨论】:

  • 看看stackoverflow.com/questions/900392/… 是否有帮助。如果您遇到任何问题,请在评论中告诉我。
  • 当您致电new_foo.bar(baz) 时,您希望返回什么。是新的Foo 实例吗?
  • @AbdulNiyasPM @hygull 与new_foo 相同的实例我已编辑问题以进行澄清
  • @Legit Stack 如果是这种情况,你不能用self调用函数(在这种情况下为baz)吗?(即return func(self)
  • @AbdulNiyasPM 哦,是的,我认为修改为bar 会起作用

标签: python metaprogramming


【解决方案1】:

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

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\Rishikesh\Projects\Python3\try>python Get_caller_object_final.py
# <__main__.Foo object at 0x0000015C5A2F59E8>
# <class '__main__.Foo'>
参考 ”

【讨论】:

    【解决方案2】:

    使用检查:

    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
    

    或者作弊:

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-23
      • 1970-01-01
      • 2010-11-07
      • 2019-02-05
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多