【问题标题】:How to refer to a method name from with a method in Python?如何使用 Python 中的方法引用方法名称?
【发布时间】:2010-02-08 14:05:28
【问题描述】:

假设我使用foo 方法定义了以下类:

class MyClass:
    def foo(self):
        print "My name is %s" % __name__

现在当我打电话给foo() 时,我希望/希望看到这个打印出来

My name is foo  

但是我得到了

My name is __main__  

如果我将类定义放入一个名为 FooBar 的模块中,我会得到

My name is FooBar  

如果我这样做了

m = MyClass()
print m.foo.__name__

我得到的正是我想要的

My name is foo

有人可以帮助解释为什么__name__ 指的是模块而不是方法名称吗? 有没有简单的方法来获取方法名?

非常感谢

【问题讨论】:

  • 为什么需要这样做?你在解决什么问题?

标签: python methods introspection


【解决方案1】:

这就是你所追求的:


from inspect import currentframe, getframeinfo

class MyClass:
    def foo(self):
        print "My name is %s" % getframeinfo(currentframe())[2]

【讨论】:

  • 虽然这是正确的,但没有理由更喜欢它而不是在没有来自 OP 的更多信息的情况下在函数体中键入“foo”。
  • 酷,想知道是否可以制作一个装饰器以某种方式做到这一点......至少在运行装饰方法之后。也许你可以检查修饰的方法。
  • @Skurmedel: def with_name(fn): return lambda *args, **kwds: fn(fn.__name__, *args, **kwds) (吃那个,所以评论格式)你必须改变函数才能知道它被包装了(名字是第一个 arg 和 self/cls 第二个)。
  • 是的,可以这样做....可能在之前或之后打印 fn.__name__。我不知道他到底想要什么:)
  • 你建议装饰者会做什么?一个函数已经有一个__name__ 属性,问题是它很难从函数本身内部访问(如果我正确理解了这个问题)。
【解决方案2】:

名称总是指局部变量或(如果不存在)全局变量。有一个具有模块名称的全局 __name__。

class MyClass:
  def foo(self):
    print "My name is %s" % MyClass.foo.__name__

当然,这是多余的,几乎完全没有意义。只需输入方法名称:

class MyClass:
  def foo(self):
    print "My name is %s" % "foo"
    print "My name is foo"

【讨论】:

  • @Skurmedel:这总是可能的,而且对他们的伤害比对我更大(通过投票作为回应,这对我来说是净赢,甚至可以玩),但如果我错过了什么,我真的很想知道关于它。
  • 是的,我明白,只要有人表达他们的担忧,我就可以拒绝投票。
  • @Roger Pate:如果我更改方法名称,我不想花时间跟踪和更改方法中每个出现的方法名称。例如,考虑一个日志记录或调试语句,您更喜欢哪个: "entering method : foo" v/s "entering method : %s" % inspect.stack()[0][3]
【解决方案3】:

__name__ 指的是模块,因为that's what it's supposed to do。获取当前正在运行的函数的唯一方法是自省堆栈。

【讨论】:

    【解决方案4】:

    其他答案解释得很好,所以我提供了一个更具体的例子。

    name.py

    def foo():
        print "name in foo",__name__
    
    foo()
    print "foo's name",foo.__name__
    print "name at top",__name__
    

    输出

    name in foo __main__
    foo's name foo
    name at top __main__
    

    name2.py

    import name
    

    输出

    name in foo name
    foo's name foo
    name at top name
    

    注意__name__ 是如何引用模块的内置属性的?如果模块直接运行,则为__main__,如果导入,则为模块的名称。

    你应该跑过if __name__=="__main__": sn-p。

    你可以找到relevant docs here,去看看吧。祝你好运! :)

    【讨论】:

      【解决方案5】:

      inspect 模块使用自省。

      import inspect
      
      class MyClass:
          def foo(self):
              print "My name is %s" % inspect.stack()[0][3]
      

      【讨论】:

        【解决方案6】:

        看看the inspect module

        试试:

        >>> import inspect
        >>> def foo():
        ...     print inspect.getframeinfo(inspect.currentframe())[2]
        ...
        >>> foo()
        foo
        

        或:

        >>> def foo2():
        ...     print inspect.stack()[0][3]
        ...
        >>> foo2()
        foo2
        

        【讨论】:

          【解决方案7】:

          这样就可以了:

          (需要参考self.__class__._name__。)

          class MyClass:
              def foo(self):
                  print "My name is %s" % self.__class__.__name__
          

          【讨论】:

          • 所需的行为,如示例所示,打印“foo”(方法名称)而不是“MyClass”。
          猜你喜欢
          • 1970-01-01
          • 2021-05-28
          • 2015-06-17
          • 2013-07-18
          • 2011-01-13
          • 2018-02-08
          • 1970-01-01
          • 2013-07-07
          相关资源
          最近更新 更多