在Python中,我想编写一个函数,如果它自己调用的话,它会将其结果漂亮地打印到控制台(主要用于交互使用或调试)。出于这个问题的目的,假设它检查某事物的状态。如果我打电话
check_status()
我想看到类似的东西:
Pretty printer status check 0.02v
NOTE: This is so totally not written for giant robots
=================================
System operational: ... ok
Time to ion canon charge is 9m 21s
Booster rocket in AFTERBURNER state
Range check is optimal
Rocket fuel is 10h 19m 40s to depletion
Beer served is type WICKSE LAGER, chill optimal
Suggested catchphrase is 01_FIGHTING_SPIRIT_GOGOGO
Virtual ... on
但是,如果我在变量赋值的上下文中调用它,我还希望它将输出作为列表传递:
not_robot_stat = check_status()
print not_robot_stat
>>> {'cond_op': 1, 't_canoncharge': 1342, 'stage_booster': 5, 'range_est_sigma': 0.023, 'fuel_est': 32557154, 'beer_type': 31007, 'beer_temp': 2, 'catchphrase_suggestion': 1023, 'virtual_on': 'hell yes'}
那么...有没有一种方法可以动态地知道函数内其输出是否被分配?我希望能够做到这一点,而无需诉诸参数传递,或编写另一个专用于此的函数。我用谷歌搜索了一下,据我所知,看起来我不得不求助于字节码。这真的有必要吗?
新解决方案
这是一个新的解决方案,通过检查其自身的字节码来检测函数的结果何时用于分配。没有完成字节码编写,它甚至应该与Python的未来版本兼容,因为它使用opcode模块进行定义。
import inspect, dis, opcode
def check_status():
try:
frame = inspect.currentframe().f_back
next_opcode = opcode.opname[ord(frame.f_code.co_code[frame.f_lasti+3])]
if next_opcode == "POP_TOP":
# or next_opcode == "RETURN_VALUE":
# include the above line in the if statement if you consider "return check_status()" to be assignment
print "I was not assigned"
print "Pretty printer status check 0.02v"
print "NOTE: This is so totally not written for giant robots"
return
finally:
del frame
# do normal routine
info = {'cond_op': 1, 't_canoncharge': 1342, 'stage_booster': 5}
return info
# no assignment
def test1():
check_status()
# assignment
def test2():
a = check_status()
# could be assignment (check above for options)
def test3():
return check_status()
# assignment
def test4():
a = []
a.append(check_status())
return a
解决方案1
这是旧的解决方案,它会在 python -i 或 PDB 下调试时检测您何时调用该函数。
import inspect
def check_status():
frame = inspect.currentframe()
try:
if frame.f_back.f_code.co_name == "<module>" and frame.f_back.f_code.co_filename == "<stdin>":
print "Pretty printer status check 0.02v"
print "NOTE: This is so totally not written for giant robots"
finally:
del frame
# do regular stuff
return {'cond_op': 1, 't_canoncharge': 1342, 'stage_booster': 5}
def test():
check_status()
>>> check_status()
Pretty printer status check 0.02v
NOTE: This is so totally not written for giant robots
{'cond_op': 1, 't_canoncharge': 1342, 'stage_booster': 5}
>>> a=check_status()
Pretty printer status check 0.02v
NOTE: This is so totally not written for giant robots
>>> a
{'cond_op': 1, 't_canoncharge': 1342, 'stage_booster': 5}
test()
>>>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)