以下是 FileCookieJar 和 MozillaCookieJar 实现的 cookiejar.py 文件的派生摘录。 https://github.com/python/cpython/blame/main/Lib/http/cookiejar.py#L1802
class FCJ():
def __init__(self):
pass
def load(self):
self.__really_load()
class MCJ(FCJ):
def __init__(self):
super().__init__()
def __really_load(self):
pass
if __name__ == "__main__":
m = MCJ()
f = FCJ()
print(m, f)
对于 FCJ 类,load 正在调用一个函数
__really_load
,该函数未在其构造中定义。它首先在子类“MCJ”中定义,根据我的理解,FCJ 不应该有任何信息,除非它是作为 MCJ 创建的一部分创建的。这似乎是某种抽象类实现。
但是为什么 python 在执行此操作时在初始检查期间不会失败?
我使用的是python3.7,代码自python2.4以来一直存在,所以我认为我遗漏了一些关于python在执行过程中如何实际解析文件错误的非常基本的东西,但我无法理解是什么。
Python 仅在运行前检查语法错误。在实践中,即使这种情况通常发生在运行时,即执行
import
语句时。
注意这一点:
faultymodule.py
:
# This module contains invalid Python code
def bar() # <-- missing colon
print("xx")
main.py
:
if __name__ == "__main__":
print("This will be printed before the error is raised")
import faultymodule # <-- The error will only be raised during the execution of this line
运行
main.py
将开始运行您的代码,正如您从打印语句中看到的那样。
对于您的具体示例,Python 不会在运行时之前检查
_really_load
是否已定义,这是该语言的一个特性。只要在调用 FCJ.load()
之前定义函数,代码就能正常执行。
例如:
class FCJ:
def load(self):
self._really_load()
if __name__ == "__main__":
f = FCJ()
# Calling f.load() now would trigger an AttributeError
def foo():
print("xx")
f._really_load = foo
# But calling f.load() now executes fine
f.load()
顺便说一下,我这里把
__really_load
换成了_really_load
。您知道双前导下划线的重要性吗? 在此处查看有关名称修改的更多信息。