Определите, доступна ли функция в модуле 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(...)
Мысли?
EDIT Как отметил Паоло, этот вопрос почти дублируется вопроса об определении наличия атрибута. Однако, поскольку используемая терминология является непересекающейся (lk "объект имеет атрибут", а мой модуль имеет функцию "), может быть полезно сохранить этот вопрос для поиска, если они не могут быть объединены.
Ответы
Ответ 1
hasattr()
- лучший выбор. Пойдите с этим.:)
if hasattr(socket, 'fromfd'):
pass
else:
pass
РЕДАКТИРОВАТЬ. На самом деле, согласно документам, которые все hasattr делает, вызывается getattr и перехватывает исключение. Поэтому, если вы хотите вырезать среднего человека, вы должны пойти с ответом marcog.
EDIT. Я также понял, что этот вопрос на самом деле является duplicate. Один из ответов там обсуждает достоинства двух вариантов, которые у вас есть: ловить исключение ( "проще просить прощения, чем разрешение" ) или просто проверять перед собой ( "смотреть, прежде чем прыгать" ). Честно говоря, я больше отношусь к последним, но похоже, что сообщество Python склоняется к прежней школе мысли.
Ответ 2
Или просто используйте блок try..except:
try:
sock = socket.fromfd(...)
except AttributeError:
sock = socket.socket(...)
Ответ 3
hasattr (obj, 'attributename'), вероятно, лучше. hasattr попытается получить доступ к атрибуту, и если он там не будет, он вернет false.
Возможно, в питоне есть динамические методы, т.е. методы, созданные при попытке получить к ним доступ. Они не были бы в директории (...). Однако 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