确定一个函数在 Python 模块中是不是可用

Posted

技术标签:

【中文标题】确定一个函数在 Python 模块中是不是可用【英文标题】: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 的 “对象具有属性” 与我的 “模块具有功能”),因此保留此问题的可搜索性可能会有所帮助,除非两者可以结合。

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

"不应使用 hasattr,因为它会吞下包括 KeyboardInterrupt 在内的异常。" (c) doc.bazaar.canonical.com/developers/…,所以 getattr 是一件好事。【参考方案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

【讨论】:

以上是关于确定一个函数在 Python 模块中是不是可用的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 DLL 中可用的函数以在 Python 中使用

如何列出 Python 模块中的所有函数?

如何列出 Python 模块中的所有函数?

如何编写一个函数来检查模块列表是不是存在,否则在 Python 中安装模块

Python:从 C 函数中确定模块名称

python中是不是有一个函数可以确定图中指定点的颜色?