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

时间:2022-05-30 09:16:42

I am working on some Python socket code that's using the socket.fromfd() function.

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

However, this method is not available on all platforms, so I am writing some fallback code in the case that the method is not defined.

但是,此方法并非在所有平台上都可用,因此在未定义方法的情况下,我正在编写一些回退代码。

What's the best way to determine if a method is defined at runtime? Is the following sufficient or is there a better idiom?

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

if 'fromfd' in dir(socket):
    sock = socket.fromfd(...)
else:
    sock = socket.socket(...)

I'm slightly concerned that the documentation for dir() seems to discourage its use. Would getattr() be a better choice, as in:

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

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

Thoughts?

EDIT As Paolo pointed out, this question is nearly a duplicate of a question about determining attribute presence. However, since the terminology used is disjoint (lk's "object has an attribute" vs my "module has a function") it may be helpful to preserve this question for searchability unless the two can be combined.

编辑正如Paolo所指出的,这个问题几乎与确定属性存在的问题重复。但是,由于使用的术语是不相交的(lk的“对象有一个属性”vs我的“模块有一个函数”),保留这个问题以获得可搜索性可能会有所帮助,除非这两个问题可以合并。

3 个解决方案

#1


30  

hasattr() is the best choice. Go with that. :)

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

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

EDIT: Actually, according to the docs all hasattr is doing is calling getattr and catching the exception. So if you want to cut out the middle man you should go with marcog's answer.

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

EDIT: I also just realized this question is actually a duplicate. One of the answers there discusses the merits of the two options you have: catching the exception ("easier to ask for forgiveness than permission") or simply checking before hand ("look before you leap"). Honestly, I am more of the latter, but it seems like the Python community leans towards the former school of thought.

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

#2


24  

Or simply use a try..except block:

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

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

#3


3  

hasattr(obj, 'attributename') is probably a better one. hasattr will try to access the attribute, and if it's not there, it'll return false.

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

It's possible to have dynamic methods in python, i.e. methods that are created when you try to access them. They would not be in dir(...). However hasattr would check for it.

在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

#1


30  

hasattr() is the best choice. Go with that. :)

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

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

EDIT: Actually, according to the docs all hasattr is doing is calling getattr and catching the exception. So if you want to cut out the middle man you should go with marcog's answer.

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

EDIT: I also just realized this question is actually a duplicate. One of the answers there discusses the merits of the two options you have: catching the exception ("easier to ask for forgiveness than permission") or simply checking before hand ("look before you leap"). Honestly, I am more of the latter, but it seems like the Python community leans towards the former school of thought.

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

#2


24  

Or simply use a try..except block:

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

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

#3


3  

hasattr(obj, 'attributename') is probably a better one. hasattr will try to access the attribute, and if it's not there, it'll return false.

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

It's possible to have dynamic methods in python, i.e. methods that are created when you try to access them. They would not be in dir(...). However hasattr would check for it.

在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