确定Python模块中是否有可用的函数

时间:2009-04-18 19:06:00

标签: python

我正在研究一些使用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的“对象具有属性” vs my “模块具有函数”),因此保留此问题以进行搜索可能会有所帮助,除非两者可以合并。

3 个答案:

答案 0 :(得分:37)

hasattr()是最佳选择。去吧。 :)

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

编辑:实际上,根据文档,所有hasattr正在做的是调用getattr并捕获异常。因此,如果你想要削减中间人,你应该选择marcog的答案。

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

答案 1 :(得分:24)

或者只是使用try..except块:

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

答案 2 :(得分: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