确定一个函数在 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 模块中是不是可用的主要内容,如果未能解决你的问题,请参考以下文章