确定函数在python模块中是否可用

Determine if a function is available in a Python module

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

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

确定方法是否在运行时定义的最佳方法是什么?以下是充分的还是有更好的成语?

1
2
3
4
if 'fromfd' in dir(socket):
    sock = socket.fromfd(...)
else:
    sock = socket.socket(...)

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

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

思想?

正如保罗指出的那样,这个问题几乎是关于确定属性存在的问题的一个副本。但是,由于所使用的术语是不相交的(LK的"对象具有属性"而我的"模块具有函数"),除非两者可以组合,否则保留此问题以便于搜索可能会有所帮助。


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

1
2
3
4
if hasattr(socket, 'fromfd'):
    pass
else:
    pass

编辑:实际上,根据文档,hasattr所做的一切都是调用getattr并捕获异常。所以,如果你想删掉中间人,你应该用马可的回答。

编辑:我也意识到这个问题实际上是一个复制品。其中一个答案讨论了你有两个选择的优点:抓住例外("请求宽恕比允许更容易")或只是在手前检查("跳跃前看")。老实说,我更倾向于后者,但Python社区似乎倾向于以前的思想流派。


或者简单地使用一个try..except块:

1
2
3
4
try:
  sock = socket.fromfd(...)
except AttributeError:
  sock = socket.socket(...)


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

在python中有可能有动态方法,也就是说,当您试图访问它们时创建的方法。它们不会在目录中(…)。但是哈萨特会检查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> 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