python-3.x - Wrapper/decorator - 获取它执行的方法的变量的值
问题描述
在包装器/装饰器中,是否有可能在它执行的方法中获取变量的值?
在这个例子中,我想直接在包装器中打印变量helloThere的内容。
实际上,我需要直接从包装器中根据这个变量执行一些其他命令(在另一个类中)。
from functools import wraps
class myclass:
def __init__(self):
pass
def _wrapped(f):
@wraps(f)
def wrapper(self, *args, **kwargs):
print(helloThere)
return wrapper
@_wrapped
def doA(self):
helloThere = "Obi-Wan Kenobi"
@_wrapped
def doB(self):
helloThere = "General Grievous"
先感谢您!
解决方案
神圣的黑客,这没有优化,可能有十亿种出错的地方,但它显示了 Python 是多么的神奇。
如果那里有更优雅的东西,我会很感兴趣。
(如果您选择使用它,您的任务是融入装饰器。)
from dill.source import getsourcelines
# Some arbitrary method, that the decorator would wrap.
def print_hi():
var = 1
var2 = 2
return var2
# converts the print_hi method into lines of code
lines = getsourcelines(print_hi)[0]
# rebuild, yielding the variable you want after it is defines.
# you would need to add some complexity to search for the variable
# definition
new_lines = [lines[0], lines[1], " yield var\n", lines[2], lines[3]]
# Re - hydrate into code
f = ''.join(new_lines)
# Make the function return statement a yield statement, so you
# can get at it.
f = f.replace("return", "yield")
# re-define the method. Note, you would probably want to replace
# the method name as well so you don't monkey patch it everywhere
# it is used.
exec(f)
# In your decorator, you can now for-loop on the function, since you
# converted it to yield instead of return.
for i in print_hi():
print(i)
同样,这只是一个概念证明。让它变得健壮需要做很多工作——但它是可以做到的。
推荐阅读
- python - Django modelform 没有插入数据
- c++ - 调用非静态函数作为谓词?
- events - Roblox 触摸事件仅适用于脚
- java - Java:如何查看字符串池中存储了多少字符串?
- python - mrjob add_file_arg() csv 文件
- c - 为什么 main char **argv 的参数是 c 中的字符串数组
- python - 我可以在 django-tables2 中制作一个二维表吗?
- python - 什么是 AttributeError: 'str' object has no attribute 'length_$rn$' on line 4 错误?
- sql - 在 SQL 中的视图上触发 DML 操作
- python-3.x - 尝试构建一个返回中位数的函数,不断收到“索引浮点数而不是整数”错误