某些背景:
我正在尝试编写一个用于记录的装饰器。具体来说,我与arcpy
合作很多,从工具中获取消息的方法是使用arcpy.GetMessages()
。但是,这是一种烦人的功能,因为它只保存最新的消息,并且必须在每个工具之后调用。伪代码示例
import arcpy
import logging
log = logging.getLogger(__name__)
def test_function(in_data):
out_data = 'C:/new_path/out_data'
arcpy.MakeFeatureLayer_management(in_data, out_data)
log.info(arcpy.GetMessages())
arcpy.Delete_management(in_data)
log.info(arcpy.GetMessages())
# If you did log.info(arcpy.GetMessages()) again here you'd just get
# the message from the Delete tool again
编写一个可以识别调用arcpy
函数的任何时间并记录它的装饰器会好得多。像:
def log_the_arcpy(fn):
@functools.wraps(fn)
def inner(*args, **kwargs):
result = fn(*args, **kwargs)
# Some magic happens here?!
if module_parent == arcpy: #module_parent is obviously fake, is there a real attribute?
log.info(arcpy.GetMessages())
return result
return inner
但是,我完全陷入两个地方:(1)如何识别单个功能的“arcpy-ness”(或任何包),以及(2)总体方法使用装饰器挖掘函数内部并确定潜在的许多函数调用的包成员资格。
似乎有用的比特是:
hasattr
(但似乎不太正确/可能很慢?)inspect
和/或生成器暂停执行的魔法这些都没有得到很好的充实 - 这是因为其中许多主题对我来说都是新鲜事。我会很感激任何方向 - 我想尽早提问,所以我以后不会被问到一堆XY Problem questions。
答案 0 :(得分:1)
如果你要直接在arcpy
上调用方法,那么包装模块可能是最简单且性能影响最小的方法:
# arcpy_proxy.py
import arcpy as _arcpy
import logging
class _proxy(object):
def __getattr__(self, item):
ref = getattr(_arcpy, item)
if callable(ref): # wrap only function calls
return self._wrap(ref)
return ref
@classmethod
def _wrap(cls, func):
def inner(*args, **kwargs):
val = func(*args, **kwargs)
logging.info(_arcpy.GetMessages()) # log the messages
return val
return inner
arcpy = _proxy()
然后你可以from arcpy_proxy import arcpy
作为替补。您甚至可以在主脚本中添加sys.modules["arcpy"] = arcpy
(在导入课程后),这样您就不必在其他任何地方替换它来代理它。
答案 1 :(得分:0)
这应该有效:
void increment(int *num) {
*num = *num + 1;
}
int main() {
int num = 0;
for (int i = 0; i < 100; i++) {
increment(&num);
}
printf("%d\n", num); // this prints 100
}
全功能:
if hasattr(fn, '__module__') and getattr(fn, '__module__') == 'arcpy':
log.info(arcpy.GetMessages())