【问题标题】:Python: how to check if optional argument can be used?Python:如何检查是否可以使用可选参数?
【发布时间】:2015-09-30 18:49:29
【问题描述】:

使用 urllib2,最新版本允许在调用 urlopen 时使用可选参数“context”。

我整理了一些代码来使用它:

# For Python 3.0 and later
from urllib.request import urlopen, HTTPError, URLError
except ImportError:
# Fall back to Python 2's urllib2
from urllib2 import urlopen, HTTPError, URLError
import ssl

context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
response = urlopen(url=url, context=context)

用我的 python 2.78 运行它...我明白了:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
  context = ssl.create_default_context()
  AttributeError: 'module' object has no attribute 'create_default_context'

所以我想:那就去python3吧;现在我得到了:

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    response = urlopen(url=url, context=context)
TypeError: urlopen() got an unexpected keyword argument 'context'

我花了一段时间才发现使用该命名参数上下文...还需要比我的 ubuntu 14.04 上安装的 3.4.0 更新的 python 版本。

我的问题:在调用 urlopen 时检查“上下文”是否可以使用的“规范”方法是什么?只需调用它并期待 TypeError?或者对我正在运行的 python 做一个确切的版本检查?

我确实在这里和谷歌搜索过,但也许我只是错过了正确的搜索词......因为我找不到任何有用的东西......

【问题讨论】:

    标签: python urllib2 optional-parameters


    【解决方案1】:

    这里描述了如何检查函数的签名:How can I read a function's signature including default argument values?

    但是,一些函数具有通用签名,例如:

    def myfunc(**kwargs):
        print kwargs.items()
    
        if kwargs.has_key('foo'):
            ...
    
        if kwargs.has_key('bar'):
            ...
    

    在调用它们之前不可能知道它们使用了哪些参数。例如matplotlib/pylab有很多这样的功能使用kwargs

    【讨论】:

    • 虽然你实际上并没有这么说,但你的回答只是强化了@meuh's
    • 我理解关于EAFP的说法;但是我有很强的java背景;因为首先请求许可在精神上要容易得多。我只是无法忍受提出例外的想法......我将来不得不担心一些微妙的细节稍后会发生变化;我抓错了东西或其他什么。所以你的回答指出的inspect.getfullargspec正是我将要使用的。
    • @Jägermeister:每次使用for 循环时,它都会以引发然后捕获StopIteration 结束。你需要习惯在 Python 中大量使用异常。
    【解决方案2】:

    使用 try/except。见python glossary

    EAFP

    请求宽恕比请求许可更容易。这种常见的 Python 编码风格假设存在有效的键或属性,如果假设被证明是错误的,则捕获异常。这种干净快速的风格的特点是存在许多 try 和 except 语句。该技术与许多其他语言(如 C)常见的 LBYL 风格形成鲜明对比。

    【讨论】:

      【解决方案3】:

      检查 Python 的版本:

      import sys
      
      if sys.hexversion >= 0x03050000:
          urlopen = urllib.urlopen
      else:
          def urlopen (*args, context=None, **kwargs):
              return urllib.urlopen(*args, **kwargs)
      

      现在只需使用urlopen() 而不是urllib.urlopen()

      我认为这将在 3.5 的早期 alpha 版本中中断,但 alpha 版本意味着要中断,所以我不太关心追踪引入此论点的精确版本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-22
        • 2015-08-09
        相关资源
        最近更新 更多