将列表作为 url 值传递给 urlopen
Passing a list as a url value to urlopen
动机
受 启发 - OP 使用 urlopen()
并意外传递了 sys.argv
列表而不是字符串作为 url
。抛出此错误消息:
AttributeError: 'list' object has no attribute 'timeout'
由于 urlopen
的编写方式,错误消息本身和回溯信息不是很丰富,可能难以理解,尤其是对于 Python 新手:
Traceback (most recent call last):
File "test.py", line 15, in <module>
get_category_links(sys.argv)
File "test.py", line 10, in get_category_links
response = urlopen(url)
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 420, in open
req.timeout = timeout
AttributeError: 'list' object has no attribute 'timeout'
问题
这是我正在使用的缩短代码:
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
import sys
def get_category_links(url):
response = urlopen(url)
# do smth with response
print(response)
get_category_links(sys.argv)
我正在考虑是否可以使用 PyCharm 等智能 IDE、[=19] 等静态代码分析工具静态捕获此类错误 =] 或 pylint
,或具有 类型注释 等语言功能。
但是,我未能检测到问题:
- 对于
flake8
和 pylint
来说可能太具体了 - 他们不会警告这个问题
PyCharm
不会警告 sys.argv
被传递到 urlopen
,即使,如果您 "jump to source" of sys.argv
它定义为:
argv = [] # real value of type <class 'list'> skipped
如果我将函数参数注释为字符串并传递sys.argv
,也没有警告:
def get_category_links(url: str) -> None:
response = urlopen(url)
# do smth with response
get_category_links(sys.argv)
问题
是否可以静态捕获此问题(无需实际执行代码)?
您可以使用 mypy 来分析您的代码,而不是让它保持特定于编辑器。这样它将在所有开发环境中 运行 而不是仅针对那些使用 PyCharm.
的人
from urllib.request import urlopen
import sys
def get_category_links(url: str) -> None:
response = urlopen(url)
# do smth with response
get_category_links(sys.argv)
response = urlopen(sys.argv)
mypy针对上述代码指出的问题:
error: Argument 1 to "get_category_links" has incompatible type List[str]; expected "str"
error: Argument 1 to "urlopen" has incompatible type List[str]; expected "Union[str, Request]"
这里的Mypy可以猜到sys.argv
的类型,因为它在存根文件中有定义。不过现在一些标准库模块仍然是 missing from typeshed
,所以你要么贡献它们,要么忽略相关的错误,直到它们被添加 :-)。
什么时候 运行 mypy?
要捕获此类错误,您可以在 CI 工具中对带有注释的文件进行 mypy 测试。 运行 在项目中的所有文件上它可能需要一些时间,对于一个小项目它是你的选择。
添加一个预提交挂钩 运行s mypy on staged files 并立即指出问题(如果需要一段时间,开发人员可能会有点烦)。
首先,你需要检查 url 类型是否为字符串,如果是字符串则检查 ValueError exception(Valid url)
import sys
from urllib2 import urlopen
def get_category_links(url):
if type(url) != type(""): #Check if url is string or not
print "Please give string url"
return
try:
response = urlopen(url)
# do smth with response
print(response)
except ValueError: #If url is string but invalid
print "Bad URL"
get_category_links(sys.argv)
动机
受 urlopen()
并意外传递了 sys.argv
列表而不是字符串作为 url
。抛出此错误消息:
AttributeError: 'list' object has no attribute 'timeout'
由于 urlopen
的编写方式,错误消息本身和回溯信息不是很丰富,可能难以理解,尤其是对于 Python 新手:
Traceback (most recent call last):
File "test.py", line 15, in <module>
get_category_links(sys.argv)
File "test.py", line 10, in get_category_links
response = urlopen(url)
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 420, in open
req.timeout = timeout
AttributeError: 'list' object has no attribute 'timeout'
问题
这是我正在使用的缩短代码:
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
import sys
def get_category_links(url):
response = urlopen(url)
# do smth with response
print(response)
get_category_links(sys.argv)
我正在考虑是否可以使用 PyCharm 等智能 IDE、[=19] 等静态代码分析工具静态捕获此类错误 =] 或 pylint
,或具有 类型注释 等语言功能。
但是,我未能检测到问题:
- 对于
flake8
和pylint
来说可能太具体了 - 他们不会警告这个问题 PyCharm
不会警告sys.argv
被传递到urlopen
,即使,如果您 "jump to source" ofsys.argv
它定义为:argv = [] # real value of type <class 'list'> skipped
如果我将函数参数注释为字符串并传递
sys.argv
,也没有警告:def get_category_links(url: str) -> None: response = urlopen(url) # do smth with response get_category_links(sys.argv)
问题
是否可以静态捕获此问题(无需实际执行代码)?
您可以使用 mypy 来分析您的代码,而不是让它保持特定于编辑器。这样它将在所有开发环境中 运行 而不是仅针对那些使用 PyCharm.
的人from urllib.request import urlopen
import sys
def get_category_links(url: str) -> None:
response = urlopen(url)
# do smth with response
get_category_links(sys.argv)
response = urlopen(sys.argv)
mypy针对上述代码指出的问题:
error: Argument 1 to "get_category_links" has incompatible type List[str]; expected "str"
error: Argument 1 to "urlopen" has incompatible type List[str]; expected "Union[str, Request]"
这里的Mypy可以猜到sys.argv
的类型,因为它在存根文件中有定义。不过现在一些标准库模块仍然是 missing from typeshed
,所以你要么贡献它们,要么忽略相关的错误,直到它们被添加 :-)。
什么时候 运行 mypy?
要捕获此类错误,您可以在 CI 工具中对带有注释的文件进行 mypy 测试。 运行 在项目中的所有文件上它可能需要一些时间,对于一个小项目它是你的选择。
添加一个预提交挂钩 运行s mypy on staged files 并立即指出问题(如果需要一段时间,开发人员可能会有点烦)。
首先,你需要检查 url 类型是否为字符串,如果是字符串则检查 ValueError exception(Valid url)
import sys
from urllib2 import urlopen
def get_category_links(url):
if type(url) != type(""): #Check if url is string or not
print "Please give string url"
return
try:
response = urlopen(url)
# do smth with response
print(response)
except ValueError: #If url is string but invalid
print "Bad URL"
get_category_links(sys.argv)