【发布时间】:2019-09-27 11:00:51
【问题描述】:
我正在为 python 中的函数制作日志装饰器:
import logging
from typing import Callable
from functools import wraps
def function_logging(fn: Callable) -> Callable:
fn_logger = logging.getLogger(fn.__module__ + '.' + fn.__name__)
@wraps(fn)
def wrapper(*args, **kwargs):
fn_logger.info("Args: {}".format(args))
fn_logger.info("Kwargs: {}".format(kwargs))
result = fn(*args, **kwargs)
fn_logger.info("Return: {}".format(result))
return result
return wrapper
PyCharm 的静态分析告诉我,我不能指望Callable 具有__module__ 属性。到目前为止,我还没有遇到过失败的情况。有谁知道在什么情况下可能会遇到没有__module__ 属性的Callable?
【问题讨论】:
-
据我所知,通常唯一没有
__module__属性的东西是内置类型的实例。但是,这些都不是可调用的。我不确定元类是否可以防止在类、其实例或方法上添加__module__(即使可以,我也不确定它是否安全)。我能够找到一种边缘案例。内置类型的方法描述符,如range.count(可调用)没有__module__。在实例上,例如range(0).count__module__是None,除了特殊方法,例如range(0).__str__不存在的地方。 -
@jdehesa 很可能就是这样。跟进:除了
Callable,还有其他类型适合排除这些边缘情况吗? -
我不确定有什么比
Callable更精确。我什至不确定这些案例是否应该表现得像那样,这就是 PyCharm 抱怨的原因,或者对于“什么东西应该或不应该有__module__”这个问题没有确切的答案。在任何情况下,您都可以随时执行(getattr(fn, '__module__', None) or '(none)')之类的操作。 -
我会注意到
mypy对此没有任何问题。 -
@modesitt
mypy通常比 PyCharm 在后台使用的任何东西都表现得更好。
标签: python pycharm typing structural-typing