判断函数是否在Python模块中可用
我正在写一些使用Python套接字的代码,里面用到了socket.fromfd()
这个函数。
不过,这个方法并不是在所有平台上都能用,所以我正在写一些备用代码,以防这个方法不存在。
在运行时,怎么判断一个方法是否被定义了呢?下面的代码够用吗,还是有更好的写法呢?
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指出的,这个问题几乎和一个关于判断属性存在性的问题重复了。不过,由于使用的术语不同(lk说的是"对象有一个属性",而我说的是"模块有一个函数"),所以保留这个问题可能对搜索有帮助,除非这两个问题能合并在一起。
3 个回答
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
26
或者直接使用一个try..except代码块:
try:
sock = socket.fromfd(...)
except AttributeError:
sock = socket.socket(...)