gpt4 book ai didi

python - 动态检测师 future 导入

转载 作者:行者123 更新时间:2023-11-28 22:55:28 25 4
gpt4 key购买 nike

我想为符合 from __future__ import division 语句的数字制作一个特殊容器。如果我在容器定义中设置 from __future__ import division,则 everything 将被迫使用 truediv。相反,如果我以另一种方式进行,那么一切都将使用整数除法。有什么方法可以检查正在进行哪种划分? (在 Python 3 中,这是一个有争议的问题,仅适用于 2.x)

例如,这里是 file1.py:

class MySpecialContainer(object):
def __init__(self, value):
self.value = value
def div(self, other):
new_value = self.value / other
return self.__class__(new_value)
def truediv(self, other):
new_value = self.value * 1.0 / other
return self.__class__(new_value)
__div__ = div
__truediv__ = truediv

然后在 file2.py 中:

from __future__ import division
from file1 import MySpecialContainer
obj = MySpecialContainer(5)
print obj.value # 5
print obj.div(2).value # 2
print 5 / 2 # 2.5

而使用除法运算符会显式导致使用 __truediv__

print MySpecialContainer(5) / 2 # 2.5

有什么特殊的方法可以检测到并避免这个问题,或者我是否需要对我的容器做出明确的选择?

编辑:这显然是一个非常简单的例子,但我希望以更复杂的方式来做到这一点(即改变 pandas 以添加 truediv 方法并改变 div 以对环境敏感)。特别是,我想在导入时动态地执行此操作,根据导入文件进行更改(我想这会引发一系列关于首先导入哪个文件的问题,等等...)

最佳答案

这里的问题是 __future__ 语句分别应用于每个模块。虽然您可以检测它是否处于事件状态,但您只是检测它是否在您已经知道的 file1.py 中处于事件状态。

如果你只关心 CPython,你可以用 sys._getframe 做一些讨厌的事情,但我不会。*

但是,无论如何您都不必这样做。不要调用 obj.div(2),只需执行 obj/2。这将适本地调用 obj.__div__obj.__truediv__


* 如果你真的感兴趣:

if sys._getframe(1).f_code.co_flags | __future__.CO_FUTURE_DIVISION:

这会(大致)告诉您直接负责调用当前函数的作用域是否是使用 from __future__ import division 语句编译的。

但这可能不是您想要的。例如,假设 file3 没有 __future__ 语句,它创建了一个使用您的对象和 file2 的生成器表达式,它确实__future__ 语句,然后将 div 映射到该生成器上。在那种情况下,您要查看第 2 帧,而不是第 1 帧,对吗?但是你的代码怎么知道的?


在评论中:

would there be a way to check this on import and substitute the appropriate method in

请记住,每个模块仅在第一次导入时编译。因此,假设您有两个不同的文件,它们都 import file1file2 打开了 divisionfile3 没有。因为您已经将 file1 编译为适用于 file2,所以对于 file3 将是错误的。

你可以想像地编写一个导入钩子(Hook)来防止 file1sys.modules 结束,所以它们每个都以不同的副本或其他东西结束,但我不不认为这是合法的,即使它有效。

关于python - 动态检测师 future 导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16880552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com