【问题标题】:Python 2: function alias or macroPython 2:函数别名或宏
【发布时间】:2018-01-04 22:32:42
【问题描述】:

我想知道是否有办法在 Python 2.7 中为函数创建宏或别名。

示例:我正在尝试使用 logging 模块并为函数 logging.debuglogging.infologging.error 等创建别名/宏。如果我在我想要的地方使用这些函数日志,一切正常。但是,如果我尝试像这样创建一个“别名”函数包装器:

def debugLog(message):
    logging.debug(message)

...然后行号报告不再按预期工作,报告的行总是说明包装器的位置,而不是实际的日志,这没有任何实际用途。

我确实找到了这个解决方案:

import logging
from logging import info as infoLog
from logging import debug as debugLog
from logging import error as errorLog
....

...但它不适合我,因为我还创建了自己的日志记录严重性:

logging.addLevelName(60, "NORMAL")

...如果可能的话,我也想为它创建一个别名/宏,例如normalLog(message)=logging.log(60, message)?我在Python Docs 或网上找不到任何全面的内容。

【问题讨论】:

  • 这不是函数吗? def normalLog(message): logging.log(60, message)
  • 如果你只写normalLog = lambda m: logging.log(60, m)呢?
  • @OferSadan:那会出现同样的问题。
  • 对于推荐的模式,我建议查看Logging Cookbook

标签: python macros


【解决方案1】:

你可以使用functools.partial:

import functools
import logging
normalLog = functools.partial(logging.log, 60)

效果很好:

normalLog("Hey!!")
Level 60:root:Hey!!

partial 将参数绑定到函数调用并返回一个部分对象(一个包含必要信息的可调用对象),因此您也可以在addLevelName 方法中使用它:

activateLevel = functools.partial(logging.addLevelName, 60, "NORMAL")
activateLevel()

这里有一个live working example,请注意日志行已正确报告。

【讨论】:

  • @mgilson 检查实时示例,它可以正常工作。
  • 啊...但是尝试在pypy 中运行它。如果你这样做了,你会有点意外。 IOW,您依赖于 functools.partial 的实现细节。
  • 这恰好适用于 CPython,因为 C 函数在 CPython 上无法获得 Python 级堆栈条目。
【解决方案2】:

您可以使用框架对象来获取行号。可以通过多种方式获取框架对象,在下面的示例中我使用sys._getframe(),参数1给出了之前的堆栈框架。 sys._getframe() 不能保证出现在所有 Python 非 C 实现中。其他几个函数返回框架对象,包括inspect 模块。

import sys

def debugLog(message):
    line = sys._getframe(1).f_lineno
    print line, ':', message


x = 42
print x
debugLog("A")
y = x + 1
print y
debugLog("B")

给予:

42
10 : A
43
13 : B

【讨论】:

  • inspect.currentframe 可能略好于sys._getframe
猜你喜欢
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
相关资源
最近更新 更多