Python 子类化模块以弃用模块级变量/常量?
假设我有一个模块,并且我想弃用该模块中的某些内容。这对于函数来说非常简单,基本上可以使用装饰器来完成:Python 子类化模块以弃用模块级变量/常量?,python,module,Python,Module,假设我有一个模块,并且我想弃用该模块中的某些内容。这对于函数来说非常简单,基本上可以使用装饰器来完成: import warnings def deprecated(func): def old(*args, **kwargs): warnings.warn("That has been deprecated, use the new features!", DeprecationWarning) return func(*args, **kwargs)
import warnings
def deprecated(func):
def old(*args, **kwargs):
warnings.warn("That has been deprecated, use the new features!", DeprecationWarning)
return func(*args, **kwargs)
return old
@deprecated
def func():
return 10
func()
弃用警告:如果已弃用,请使用新功能
十,
然而,如果我想反对一个不平凡的常量,就没有办法对变量应用装饰器。我在玩游戏,似乎可以对模块进行子类化,并使用\uuu getattribute\uuu
发出警告:
我在这里使用NumPy只是为了说明以下原则:
import numpy as np
class MyMod(type(np)): # I could also subclass "types.ModuleType" instead ...
def __getattribute__(self, name):
if name in {'float', 'int', 'bool', 'complex'}:
warnings.warn("that's deprecated!", DeprecationWarning)
return object.__getattribute__(self, name)
np.__class__ = MyMod
np.float
弃用警告:这是弃用的
浮动
然而,这似乎不可能从包内实现(至少在顶层),因为我无法访问自己的模块。我必须创建另一个包来修补主包
有没有更好的方法来“弃用”从包中访问变量,而不是将“module”类划分为子类和/或使用一个元包来修补另一个包的顶级模块?已被接受,并将添加到Python 3.7中(在编写时未发布),这将允许(或至少大大简化)弃用模块级常量
它通过在模块中添加一个\uu getattr\uu
函数来工作。例如,在这种情况下:
import builtins
import warnings
def __getattr__(name):
if name == 'float':
warnings.warn("That has been deprecated, use the new features!", DeprecationWarning)
return builtins.float
raise AttributeError(f"module {__name__} has no attribute {name}")
这基本上就是政治公众人物中的例子,稍微适合这个问题。我有点困惑。你控制包裹,对吗?除非您将所有内容都放在一个大文件中,否则您应该能够将所有本地实例更改为不再是问题,然后使用您描述的getter。您的目标是哪个版本的Python?另外,从3.4上的一些实验来看,您似乎可以使用
sys.modules.get(\uuu name\uuuuuuuuuuu)
获得当前模块对象,或许可以尝试使用monkey补丁或其他方法-尽管\uuuuuu class\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>赋值似乎不起作用。也许其他人可以用它运行。@DavidZ如果它适用于所有最新的Python版本(2.7和3.4+),那就最好了,但如果它只是Python 3.5和3.6,那就没问题了。使用sys.modules.get(\uu name\uuu)
,这实际上是一个不错的主意-我会看看我是否能做到这一点。@minitontet它对顶级文件(模块)特别有意思,因为我把这些变量放在那里…请参阅Alex Martelli的ActiveState配方,标题为“非常类似的东西”。