[英]How to extend built-in classes in python
我正在使用micro-python为esp8266微控制器编写一些代码,它具有一些不同的类以及内置类标准中的一些其他方法。 为了允许我在桌面上进行调试,我构建了一些帮助程序类,以便代码可以运行。 但是我遇到了带有micro-pythons时间函数的障碍,该函数具有time.sleep_ms方法,因为micropython上的标准time.sleep方法不接受浮点数。 我尝试使用以下代码扩展内置的时间类,但无法正确导入。 有什么想法吗?
class time(time):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def sleep_ms(self, ms):
super().sleep(ms/1000)
此代码存在于文件time.py中。 其次,我知道我必须解决要导入的time.time问题。 我也意识到我可以将其称为别的东西,并在我的微控制器代码中放入陷阱,但是我想避免在控制器中加载任何特殊功能,以节省空间和周期。
您不是要覆盖一个类,而是要猴子修补一个模块。
首先,如果您的模块名为time.py
,则永远不会优先于内置time
模块加载它。 真正内置的模块(就像编译到解释器内核中一样,不仅是CPython附带的C扩展模块)是特殊的, 它们总是在不检查sys.path
情况下加载的 ,因此您甚至无法尝试隐藏time
模块,即使您愿意(您通常也不想这样做,而且这样做非常丑陋)。 在这种情况下,内置的time
模块会给您阴影。 您根本无法以纯名称time
导入模块,因为无需查看sys.path
就可以找到内置模块。
其次,假设您使用不同的名称并仅出于猴子补丁时间目的将其导入(或做一些可怕的事情,例如将猴子补丁添加到自定义sitecustomize
模块中 ,那么使该函数真正真正地属于猴子补丁并不是sitecustomize
容易的事模块(以任何常规方式对其进行定义都会为其定义模块的范围,而不是与time
模块中其他函数的范围相同)。如果不需要将其真正地定义为time
一部分,最简单的方法是:
import time
def sleep_ms(ms):
return time.sleep(ms / 1000)
time.sleep_ms = sleep_ms
当然,如前所述, sleep_ms
仍然是模块的一部分,并带有模块的作用域(这就是为什么要进行time.sleep
,而不仅仅是sleep
;您可以from time import sleep
来避免对其进行限定,但是它仍然如果其他人稍后会修补time.sleep
则本地别名可能与time.sleep
不匹配)。
如果你想让它表现得像它的一部分time
模块,这样你就可以在引用任意事物time
的命名空间,没有资格和随时查看当前功能time
,你需要使用eval
来编译代码time
的范围:
import time
# Compile a string of the function's source to a code object that's not
# attached to any scope at all
# The filename argument is garbage, it's just for exception traceback
# reporting and the like
code = compile('def sleep_ms(ms): sleep(ms / 1000)', 'time.py', 'exec')
# eval the compiled code with a scope of the globals of the time module
# which both binds it to the time module's scope, and inserts the newly
# defined function directly into the time module's globals without
# defining it in your own module at all
eval(code, vars(time))
del code, time # May as well leave your monkey-patch module completely empty
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.