我有一个Python装饰器,我用它来标记函数/方法已弃用。它足够,但我希望它能够更好地。具体来说,我想要它做的是能够告诉的完全行号已弃用的函数。这样就不必通过源代码来查找它了;相反,警告会将它们直接指向它。 (这并不是说有人不会通过代码来查找其他使用调用已弃用函数的地方,但他们不应该这样做以响应这样的警告,恕我直言。)
class deprecated(object):
'''This class implements the deprecated decorator.
This decorator is used to mark a function or a class as
deprecated. A message indicating why it is deprecated (and what
to use instead) must be provided. Also, a version number
indicating when the function or class was deprecated must _also_
be provided.
Optionally, a third parameter may be passed that indicates when
the deprecated functionality will actually be removed.'''
def __init__(self, message, version, to_be_removed_in_version = None):
self._message = message
self._version = version
self._removal_version = to_be_removed_in_version
return
def __call__(self, func):
def wrapper(*args, **kwargs):
import warnings
import inspect
frame = inspect.currentframe().f_back
where = 'Called from {0} somewhere after line {1}.'
where = where.format(frame.f_code.co_filename,
frame.f_code.co_firstlineno)
msg = 'Call to deprecated function {0} (since {1}{2}) {3}'
if self._removal_version is not None:
removal = ', scheduled for removal by version {0}'
removal = removal.format(self._removal_version)
msg = msg.format(func.__name__, self._version,
removal, where)
warnings.warn_explicit(msg, category = DeprecationWarning,
filename = func.func_code.co_filename,
lineno = func.func_code.co_firstlineno + 1)
return func(*args, **kwargs)
wrapper.__name__ = func.__name__
wrapper.__doc__ = func.__doc__
wrapper.__dict__.update(func.__dict__)
return wrapper
答案 0 :(得分:9)
你不需要那些东西:
from functools import wraps
import warnings
def deprecated(message, newfunc):
def _deprecated(func):
@wraps(func)
def _wrapped(*args, **kwds):
warnings.warn(message + ', ' + newfunc,
DeprecationWarning, stacklevel=2)
return func(*args, **kwds)
return _wrapped
return _deprecated
这就是全部!看看:
@deprecated("function foo is deprecated", "use bar instead")
def foo(bar):
print 'Hello', bar
foo('World')
我得到了
teste.py:17: DeprecationWarning: function foo is deprecated, use bar instead
foo('World')
Hello World
另一个例子:
class Foo(object):
@deprecated("method bar is deprecated", "use baz instead")
def bar(self, baz):
print 'Goodbye', baz
f = Foo()
f.bar('World')
我明白了:
teste.py:25: DeprecationWarning: method bar is deprecated, use baz instead
f.bar('World')
Goodbye World
秘密是stacklevel
的{{1}}参数。 docs说:
stacklevel参数可以由用Python编写的包装函数使用,(...)使警告引用deprecation()的调用者,而不是引用deprecation()本身(因为后者)会破坏警告信息的目的。)