【问题标题】:Determine if a function is available in a Python module确定一个函数在 Python 模块中是否可用
【发布时间】:2010-10-20 07:44:20
【问题描述】:

我正在编写一些使用 socket.fromfd() 函数的 Python 套接字代码。

但是,这个方法并不是在所有平台上都可用,所以我写了一些回退代码,以防该方法没有定义。

确定方法是否在运行时定义的最佳方法是什么?以下是否足够或有更好的习惯用法?

if 'fromfd' in dir(socket):
    sock = socket.fromfd(...)
else:
    sock = socket.socket(...)

我有点担心dir() 的文档似乎不鼓励使用它。 getattr() 会是更好的选择吗,例如:

if getattr(socket, 'fromfd', None) is not None:
    sock = socket.fromfd(...)
else:
    sock = socket.socket(...)

想法?

编辑正如Paolo 指出的,这个问题是nearly a duplicate 的关于确定属性存在的问题。但是,由于所使用的术语是不相交的(lk 的 “对象具有属性” 与我的 “模块具有功能”),因此保留此问题的可搜索性可能会有所帮助,除非两者可以结合。

【问题讨论】:

    标签: python


    【解决方案1】:

    hasattr() 是最好的选择。随它去吧。 :)

    if hasattr(socket, 'fromfd'):
        pass
    else:
        pass
    

    编辑:实际上,根据文档,所有 hasattr 所做的只是调用 getattr 并捕获异常。所以如果你想去掉中间人,你应该选择 marcog 的答案。

    编辑:我也刚刚意识到这个问题实际上是duplicate。那里的答案之一讨论了您拥有的两个选项的优点:捕获异常(“比许可更容易请求宽恕”)或只是事先检查(“在你跳跃之前查看”)。老实说,我更倾向于后者,但 Python 社区似乎更倾向于前者。

    【讨论】:

    【解决方案2】:

    或者干脆使用 try..except 块:

    try:
      sock = socket.fromfd(...)
    except AttributeError:
      sock = socket.socket(...)
    

    【讨论】:

    • 我相信如果它不存在会抛出一个 AttributeError,而不是一个 NameError
    • 这是最pythonic的解决方案。
    【解决方案3】:

    hasattr(obj, 'attributename') 可能是一个更好的选择。 hasattr 将尝试访问该属性,如果它不存在,它将返回 false。

    在 python 中可以有动态方法,即当你尝试访问它们时创建的方法。他们不会在 dir(...) 中。但是 hasattr 会检查它。

    >>> class C(object):
    ...   def __init__(self):
    ...     pass
    ...   def mymethod1(self):
    ...     print "In #1"
    ...   def __getattr__(self, name):
    ...     if name == 'mymethod2':
    ...       def func():
    ...         print "In my super meta #2"
    ...       return func
    ...     else:
    ...       raise AttributeError
    ... 
    >>> c = C()
    >>> 'mymethod1' in dir(c)
    True
    >>> hasattr(c, 'mymethod1')
    True
    >>> c.mymethod1()
    In #1
    >>> 'mymethod2' in dir(c)
    False
    >>> hasattr(c, 'mymethod2')
    True
    >>> c.mymethod2()
    In my super meta #2
    

    【讨论】:

      猜你喜欢
      • 2015-05-19
      • 1970-01-01
      • 2015-03-16
      • 2012-02-06
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 2023-02-04
      相关资源
      最近更新 更多