将列表作为 url 值传递给 urlopen

问题描述 投票:0回答:2

动机

这个问题的启发 - OP正在使用

urlopen()
并且意外地传递了
sys.argv
列表而不是字符串作为
url
。抛出此错误消息:

属性错误:“列表”对象没有属性“超时”

由于

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、flake8

pylint
 等静态代码分析工具,或者使用 
类型注释 等语言功能来静态捕获此类错误。

但是,我没能发现问题:

  • 对于

    flake8

    pylint
     来说可能太具体了 - 他们不会警告问题

  • PyCharm

     不会警告 
    sys.argv
     被传递到 
    urlopen
    ,尽管如此,如果您“跳转到 
    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)
    
    

问题

是否可以静态地捕获这个问题(无需实际执行代码)?

python pycharm python-typing urlopen
2个回答
6
投票
您可以使用

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

 的类型,因为它在其存根文件中定义。目前,一些标准库模块仍然在 
typeshed
 中缺失,因此您必须贡献它们或忽略相关错误,直到它们被添加:-)。

何时运行 mypy?

    要捕获此类错误,您可以在 CI 工具中的测试中对带有注释的文件运行 mypy。在项目中的所有文件上运行它可能需要一些时间,对于小型项目,这是您的选择。
  1. 添加一个预提交钩子,在暂存文件上运行 mypy 并立即指出问题(如果需要一段时间,可能会对开发人员有点烦人)。

0
投票

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)

	
© www.soinside.com 2019 - 2024. All rights reserved.