Python 在这种情况下,当变量被self覆盖时会发生什么情况?
我正在下载Python中的URL,需要检测404,因此经过一些搜索后,我想到:Python 在这种情况下,当变量被self覆盖时会发生什么情况?,python,Python,我正在下载Python中的URL,需要检测404,因此经过一些搜索后,我想到: import urllib class MyUrlOpener(urllib.FancyURLopener): def retrieve(self, url, filename=None, reporthook=None, data=None): self.file_was_found = True val = urllib.FancyURLopener.retrieve(se
import urllib
class MyUrlOpener(urllib.FancyURLopener):
def retrieve(self, url, filename=None, reporthook=None, data=None):
self.file_was_found = True
val = urllib.FancyURLopener.retrieve(self, url, filename, reporthook, data)
return val
def http_error_404(url, fp, errcode, errmsg, headers, data):
url.file_was_found = False
def download_file(url, saveas):
urlaccess = MyUrlOpener()
localFile, headers = urlaccess.retrieve(url, saveas)
return urlaccess.file_was_found
我的问题是,如果您查看FancyURLopener的Python 2.7源代码,您会看到:
def http_error(self, url, fp, errcode, errmsg, headers, data=None):
"""Handle http errors.
Derived class can override this, or provide specific handlers
named http_error_DDD where DDD is the 3-digit error code."""
# First check if there's a specific handler for this error
name = 'http_error_%d' % errcode
if hasattr(self, name):
method = getattr(self, name)
if data is None:
result = method(url, fp, errcode, errmsg, headers)
else:
result = method(url, fp, errcode, errmsg, headers, data)
if result: return result
return self.http_error_default(url, fp, errcode, errmsg, headers)
它将url作为第一个参数传递,而不是self。我认为函数的第一个参数总是按照约定引用类实例,我的代码证实了这一点。那么url值会发生什么变化呢
更新:结果是data==None,所以它调用了第一个签名。这挫败了我手动添加self参数的尝试。当我在http_error_404签名中为数据添加了=None默认值时,一切都很好,因为它使用了默认值
固定/正确的签名是def http_error_404self、url、fp、errcode、errmsg、headers、data=None:在Python中,任何类实例的方法都已由Python解释器传入,所有其他参数都会自动下移一位 换句话说,Python解释器重写:
urlaccess.retrieve(url, saveas)
变成这样的东西:
urlaccess.retrieve(urlaccess, url, saveas)
所以你不必自己做。但是,
显性比隐性好
为Python对象声明的任何实例方法都必须明确指定它们将对象的实例作为其第一个参数,即使Python将在程序员不执行任何操作的情况下传递该参数
第一个参数不必称为self。。。这只是一个惯例
因此,要像mluebke那样回答您的问题,您需要指定自变量
def http_error_404(url, fp, errcode, errmsg, headers, data):
url.file_was_found = False
# Python is treating `url` as `self`
# Therefore the URL is being saved in `fp`, `fp` in `errcode`, etc.
要解决此问题,请添加第一个参数以拾取实例
def http_error_404(self, url, fp, errcode, errmsg, headers, data):
self.file_was_found = False
# Now everything should work
在Python中,任何类实例的方法都已由Python解释器传入,所有其他参数都会自动下移一位 换句话说,Python解释器重写:
urlaccess.retrieve(url, saveas)
变成这样的东西:
urlaccess.retrieve(urlaccess, url, saveas)
所以你不必自己做。但是,
显性比隐性好
为Python对象声明的任何实例方法都必须明确指定它们将对象的实例作为其第一个参数,即使Python将在程序员不执行任何操作的情况下传递该参数
第一个参数不必称为self。。。这只是一个惯例
因此,要像mluebke那样回答您的问题,您需要指定自变量
def http_error_404(url, fp, errcode, errmsg, headers, data):
url.file_was_found = False
# Python is treating `url` as `self`
# Therefore the URL is being saved in `fp`, `fp` in `errcode`, etc.
要解决此问题,请添加第一个参数以拾取实例
def http_error_404(self, url, fp, errcode, errmsg, headers, data):
self.file_was_found = False
# Now everything should work
self在方法定义中显式列出,但在调用方法时隐式传递。将函数更改为这样,所有变量将再次开始排列
def http_error_404(self, url, fp, errcode, errmsg, headers, data):
self.file_was_found = False
self在方法定义中显式列出,但在调用方法时隐式传递。将函数更改为这样,所有变量将再次开始排列
def http_error_404(self, url, fp, errcode, errmsg, headers, data):
self.file_was_found = False