在Python中,不使用traceback模块,是否可以从该函数中确定函数名称?

说我有一个带功能栏的模块foo。 当执行foo.bar() ,bar是否有办法知道bar的名称? 或者更好的是foo.bar的名称?

#foo.py
def bar():print "my name is", __myname__ # <== how do I calculate this at runtime?

#1楼

functionNameAsString = sys._getframe().f_code.co_name

我想要一个非常类似的东西,因为我想将函数名称放在一个日志字符串中,该字符串在我的代码中占据了很多位置。 可能不是这样做的最佳方法,但是这是一种获取当前函数名称的方法。


#2楼

有几种方法可以得到相同的结果:

from __future__ import print_function
import sys
import inspectdef what_is_my_name():print(inspect.stack()[0][0].f_code.co_name)print(inspect.stack()[0][3])print(inspect.currentframe().f_code.co_name)print(sys._getframe().f_code.co_name)

请注意, inspect.stack调用比其他方法慢数千倍:

$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][0].f_code.co_name'
1000 loops, best of 3: 499 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][3]'
1000 loops, best of 3: 497 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.currentframe().f_code.co_name'
10000000 loops, best of 3: 0.1 usec per loop
$ python -m timeit -s 'import inspect, sys' 'sys._getframe().f_code.co_name'
10000000 loops, best of 3: 0.135 usec per loop

#3楼

我找到了一个将写函数名称的包装器

from functools import wrapsdef tmp_wrap(func):@wraps(func)def tmp(*args, **kwargs):print func.__name__return func(*args, **kwargs)return tmp@tmp_wrap
def my_funky_name():print "STUB"my_funky_name()

这将打印

my_funky_name

存根


#4楼

我将这个方便的实用程序放在附近:

import inspect
myself = lambda: inspect.stack()[1][3]

用法:

myself()

#5楼

这是一种面向未来的方法。

将@CamHart和@Yuval的建议与@RoshOxymoron的可接受答案结合起来,可以避免以下情况:

  • _hidden和可能不推荐使用的方法
  • 索引到堆栈中(可以在以后的python中重新排序)

因此,我认为这与将来的python版本(在2.7.3和3.3.2中进行测试)相匹配:

from __future__ import print_function
import inspectdef bar():print("my name is '{}'".format(inspect.currentframe().f_code.co_name))

#6楼

您可以使用装饰器:

def my_function(name=None):return namedef get_function_name(function):return function(name=function.__name__)>>> get_function_name(my_function)
'my_function'

#7楼

这实际上是从问题的其他答案中得出的。

这是我的看法:

import sys# for current func name, specify 0 or no argument.
# for name of caller of current func, specify 1.
# for name of caller of caller of current func, specify 2. etc.
currentFuncName = lambda n=0: sys._getframe(n + 1).f_code.co_namedef testFunction():print "You are in function:", currentFuncName()print "This function's caller was:", currentFuncName(1)    def invokeTest():testFunction()invokeTest()# end of file

与使用inspect.stack()相比,此版本的可能优势是它应该快数千倍[请参阅Alex Melihoff的文章和有关使用sys._getframe()与使用inspect.stack()的时序]。


#8楼

import inspectdef whoami():return inspect.stack()[1][3]def whosdaddy():return inspect.stack()[2][3]def foo():print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())bar()def bar():print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())foo()
bar()

在IDE中,代码输出

你好,我是foo,爸爸是

你好,我是酒吧,爸爸是foo

你好,我在酒吧,爸爸是


#9楼

我使用自己的方法在多重继承场景中安全地调用super(我把所有代码都放了进去)

def safe_super(_class, _inst):"""safe super call"""try:return getattr(super(_class, _inst), _inst.__fname__)except:return (lambda *x,**kx: None)def with_name(function):def wrap(self, *args, **kwargs):self.__fname__ = function.__name__return function(self, *args, **kwargs)
return wrap

样本用法:

class A(object):def __init__():super(A, self).__init__()@with_namedef test(self):print 'called from A\n'safe_super(A, self)()class B(object):def __init__():super(B, self).__init__()@with_namedef test(self):print 'called from B\n'safe_super(B, self)()class C(A, B):def __init__():super(C, self).__init__()@with_namedef test(self):print 'called from C\n'safe_super(C, self)()

测试它:

a = C()
a.test()

输出:

called from C
called from A
called from B

在每个@with_name装饰方法中,您可以访问self .__ fname__作为当前函数名称。


#10楼

print(inspect.stack()[0].function)似乎也可以工作(Python 3.5)。


#11楼

import sysdef func_name():""":return: name of caller"""return sys._getframe(1).f_code.co_nameclass A(object):def __init__(self):passdef test_class_func_name(self):print(func_name())def test_func_name():print(func_name())

测试:

a = A()
a.test_class_func_name()
test_func_name()

输出:

test_class_func_name
test_func_name

#12楼

我做了CamHart所说的:

import sys
def myFunctionsHere():print(sys._getframe().f_code.co_name)myFunctionsHere()

输出:

C:\\ Python \\ Python36 \\ python.exe C:/Python/GetFunctionsNames/TestFunctionsNames.py myFunctionsHere

流程结束,退出代码为0


#13楼

import inspectdef foo():print(inspect.stack()[0][3])print(inspect.stack()[1][3]) #will give the caller of foos name, if something called foo

#14楼

Python没有功能来访问函数或函数本身中的名称。 已经提出但遭到拒绝。 如果您不想自己玩堆栈,则应根据上下文使用"bar"bar.__name__

给定的拒绝通知是:

该PEP被拒绝。 尚不清楚在极端情况下应如何实现它或精确的语义,并且给出的重要用例还不够多。 回应充其量是冷淡的。


#15楼

我想inspect是最好的方法。 例如:

import inspect
def bar():print("My name is", inspect.stack()[0][3])

#16楼

您可以使用@Andreas Jung显示的方法来获得定义的名称,但这可能不是使用该函数调用的名称:

import inspectdef Foo():print inspect.stack()[0][3]Foo2 = Foo>>> Foo()
Foo>>> Foo2()
Foo

我不能说这种区别对您是否重要。


#17楼

使用此方法(基于#Ron Davis的答案):

import sysdef thisFunctionName():"""Returns a string with the name of the function it's called from"""return sys._getframe(1).f_code.co_name

#18楼

我最近尝试使用以上答案从该函数的上下文访问该函数的文档字符串,但是由于上述问题仅返回了名称字符串,因此它不起作用。

幸运的是,我找到了一个简单的解决方案。 如果像我一样,您想引用该函数,而不是简单地获取表示名称的字符串,您可以将eval()应用于函数名称的字符串。

import sys
def foo():"""foo docstring"""print(eval(sys._getframe().f_code.co_name).__doc__)

#19楼

我建议不要依赖堆栈元素。 如果有人在不同的上下文(例如python解释器)中使用您的代码,则您的堆栈将更改并破坏您的索引([0] [3])。

我建议你这样:

class MyClass:def __init__(self):self.function_name = Nonedef _Handler(self, **kwargs):print('Calling function {} with parameters {}'.format(self.function_name, kwargs))self.function_name = Nonedef __getattr__(self, attr):self.function_name = attrreturn self._Handlermc = MyClass()
mc.test(FirstParam='my', SecondParam='test')
mc.foobar(OtherParam='foobar')

#20楼

我不确定为什么人们会变得复杂:

import sys
print("%s/%s" %(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name))

从该函数中确定函数名称(不使用回溯)相关推荐

  1. scala 函数中嵌套函数_Scala中的VarArgs函数和@varargs批注

    scala 函数中嵌套函数 In this post, we are going to discuss about Functions with Var-Args (Variable Number O ...

  2. scala 函数中嵌套函数_Scala函数–声明,定义,调用和嵌套函数

    scala 函数中嵌套函数 A function is a set of statements combined together to perform a specific task. The co ...

  3. scala 函数中嵌套函数_Scala合成函数

    scala 函数中嵌套函数 Scala中的合成功能 (Composition function in Scala) Scala composition function is a way in whi ...

  4. python在另一个函数中使用其他函数的变量_在另一个函数中访问函数的变量,如function() . var in python...

    我在寻找一种正确的方法来访问另一个函数中的函数变量时遇到了一些问题 . 我正在制作远程操作类工具,因此我需要处理接收的命令[如'exit'或'nircmdc.exe'或'telnet'等] . 下面的 ...

  5. scala 函数中嵌套函数_Scala中的嵌套函数 用法和示例

    scala 函数中嵌套函数 Scala中的嵌套函数 (Nested functions in Scala) A nested function is defined as a function whi ...

  6. scala 函数中嵌套函数_如何在Scala中将函数转换为部分函数?

    scala 函数中嵌套函数 First, let's see what is a function and a partial function, and then we will see their ...

  7. c语言习题 定义函数 areaT,功能是求梯形面积。要求在主函数中输入上底(用变量 a存储)、下底(用变量 b 存储)、和高(用变量 h 存储),在主函数中调用函数 areaT,输出梯形面积(用变量

    定义函数 areaT,功能是求梯形面积.要求在主函数中输入上底(用变量 a存储).下底(用变量 b 存储).和高(用变量 h 存储),在主函数中调用函数 areaT,输出梯形面积(用变量 s 存储)的 ...

  8. python 从函数中返回函数

    从函数中返回函数 其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来: def hi(name="yasoob"):def greet():return &q ...

  9. matlab中push,如何在GUI中pushbutton的回调函数中嵌入函数

    在pushbutton的回调函数中加入函数后程序无法运行,具体情况如下: 程序代码: function varargout = just_try(varargin) % JUST_TRY MATLAB ...

最新文章

  1. Qt 实现QT控件中的QLabel显示图片并自适应显示
  2. burp 代理的时候无法访问https网站
  3. Java日志记录最佳实践
  4. qwtplot设置xy坐标轴原点重合_数控机床的原点、参考点以及坐标系怎么区分?不理解很容易混淆的...
  5. mysql join 组合索引,图文详解MySQL中两表关联的连接表如何创建索引
  6. 虚拟机利用Host-only实现在不插网线的情况下,虚拟机与主机实现双向通信,实现ssh连接以及samba服务实现共享...
  7. springboot集成log4j
  8. vue中自定义组件(插件)
  9. 日常Java练习题(每天进步一点点系列)
  10. 2015-2016前端知识体系(转)
  11. 在线c语言编程网站_学编程有哪些好的网站推荐?
  12. openCV专栏(二):基础计算实战+色彩空间转换
  13. 比较好用的自定义软键盘
  14. 常用1寸、2寸照片标准尺寸
  15. 牧牛海派战法,区块链对经济社会的影响
  16. 数据对象与对象之间相似度与相异度的度量
  17. model 和WEB前台页面提交完美自动填充
  18. 【蓝桥系列】——十三届蓝桥杯PythonB组第五题E题蜂巢(AC代码)
  19. 多线程系列学习:ABA问题
  20. uniapp配合colorUI制作简单的信封

热门文章

  1. const变量的使用方法。。
  2. 【剑指offer-Java版】06重建二叉树
  3. Dagger2从入门到熟练
  4. EditText(输入框)详解
  5. NSString类详解
  6. swift_023(Swift 的继承)
  7. [LeetCode]Array主题系列{35,39,40,48题}
  8. BZOJ2120 数颜色 【带修改莫队】
  9. docker 部署 nginx+php+mysql
  10. 【Beta版本】冲刺-Day6