Python проверить наличие метода

Как найти методы объекта в Python

Часто в процессе работы с Python возникает необходимость узнать, какие методы доступны для какого-то конкретного объекта. Это может быть полезно, если вы работаете с новым или незнакомым объектом, и вам нужно узнать, какие функции вы можете использовать.

Возможен и другой сценарий: например, вы знаете имя метода, но не уверены, существует ли он для данного объекта. В этом случае вы захотите проверить наличие метода, прежде чем вызывать его, чтобы избежать возможных ошибок.

Для обоих этих задач в Python существуют простые и эффективные решения.

Нахождение всех методов объекта

В Python есть встроенная функция dir() , которая возвращает список атрибутов и методов для любого объекта. Вот пример ее использования:

# Создание объекта класса list my_object = list() # Получение списка всех методов и атрибутов этого объекта methods = dir(my_object) # Вывод списка print(methods)

В результате выполнения этого кода будет выведен список всех методов и атрибутов объекта list .

Проверка наличия метода у объекта

Если вам нужно проверить, есть ли у объекта конкретный метод, вы можете воспользоваться функцией hasattr() . Она принимает два аргумента: объект и строку, содержащую имя атрибута или метода, который нужно проверить.

Вот пример использования этой функции:

# Создание объекта класса list my_object = list() # Проверка наличия метода append у объекта has_method = hasattr(my_object, 'append') # Вывод результата print(has_method)

Если метод append существует у объекта my_object , то функция hasattr() вернет True , иначе — False .

Читайте также:  One line css grid

Таким образом, с помощью функций dir() и hasattr() можно легко найти все методы объекта или проверить наличие конкретного метода.

Источник

Python проверить наличие метода

Last updated: Feb 22, 2023
Reading time · 3 min

banner

# Table of Contents

# Check if an object has a specific Method in Python

To check if an object has a specific method:

  1. Use the getattr() function to get the attribute of the object.
  2. Use the callable() function to check if the attribute is a method.
  3. If the condition is met, the object has the specified method.
Copied!
class Employee(): def __init__(self, first, last): self.first = first self.last = last def get_name(self): return f'self.first> self.last>' emp1 = Employee('bobby', 'hadz') method = getattr(emp1, 'get_name', None) if callable(method): print(method()) # 👉️ bobby hadz

We used the getattr() function to get the get_name attribute of the object.

The getattr function returns the value of the provided attribute of the object.

The function takes the object, the name of the attribute and a default value for when the attribute doesn’t exist on the object as parameters.

We used None as the default value for when the attribute doesn’t exist.

The last step is to use the callable() function to check if the attribute is a method.

The callable function takes an object as an argument and returns True if the object appears callable, otherwise False is returned.

If the specified attribute exists on the object and the attribute is callable, we can safely assume that it is a method.

Alternatively, you can use the hasattr() function.

# Check if an object has a specific Method using hasattr()

This is a three-step process:

  1. Use the hasattr() function to check if the attribute exists on the object.
  2. Use the callable() function to check if the attribute is callable.
  3. If both conditions are met, the object has the specified method.
Copied!
class Employee(): def __init__(self, first, last): self.first = first self.last = last def get_name(self): return f'self.first> self.last>' emp1 = Employee('bobby', 'hadz') if hasattr(emp1, 'get_name') and callable(emp1.get_name): print(emp1.get_name()) # 👉️ bobby hadz

The hasattr function takes the following 2 parameters:

Name Description
object The object we want to test for the existence of the attribute
name The name of the attribute to check for in the object

The hasattr() function returns True if the string is the name of one of the object’s attributes, otherwise `False` is returned.

We used the boolean AND operator, so for the if block to run both conditions have to be met.

The object has to have the specified attribute and the attribute has to be callable.

# Check if an object has a specific Method using try/except

If you use a try/except statement, you would only be checking if the attribute exists on the object, not if it’s callable.

Copied!
class Employee(): def __init__(self, first, last): self.first = first self.last = last def get_name(self): return f'self.first> self.last>' emp1 = Employee('bobby', 'hadz') try: result = emp1.get_name() except AttributeError: print('The attribute does NOT exist')

If the get_name attribute doesn’t exist on the object, an AttributeError is raised and the except block runs.

However, the attribute could exist on the object and not be callable, in which case a TypeError is raised.

The previous two approaches are more direct and explicit and do a better job at checking if an object has a specific method.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

Как проверить, существует ли метод в Python?

В функции __getattr__() , если указанная переменная не найдена, она дает ошибку. Как проверить, существует ли переменная или метод как часть объекта?

import string import logging class Dynamo: def __init__(self,x): print "In Init def" self.x=x def __repr__(self): print self.x def __str__(self): print self.x def __int__(self): print "In Init def" def __getattr__(self, key): print "In getattr" if key == 'color': return 'PapayaWhip' else: raise AttributeError dyn = Dynamo('1') print dyn.color dyn.color = 'LemonChiffon' print dyn.color dyn.__int__() dyn.mymethod() //How to check whether this exist or not 

8 ответов

Проще просить прощения, чем спрашивать разрешения.

Не проверяйте, существует ли метод. Не тратьте ни одной строки кода на «проверку»

try: dyn.mymethod() # How to check whether this exists or not # Method exists and was used. except AttributeError: # Method does not exist; What now? 

Но, возможно, он действительно не хочет вызывать его, просто чтобы проверить, существует ли этот метод (как в моем случае) .

В отличие от .NET, это на самом деле более производительно, чем проверка, существует ли метод. Я удивлен (в хорошем смысле).

как говорит @DK, это приведет к перехвату любой ошибки AttributeError, которая может быть вызвана проверяемым методом, что может быть нежелательно (не говоря уже о том, что в этом случае это приведет к неверному выводу об отсутствии метода).

@ashes999 ashes999 Не могли бы вы указать какой-нибудь официальный или хорошо документированный источник, подтверждающий это, пожалуйста?

@Rick77 Rick77 возможно мой комментарий плохо написан. В .NET исключения довольно тяжелые и медленные; Разработчик .NET проверит, существует ли метод, чтобы избежать исключения. В Python исключения довольно легкие и быстрые. У меня нет документов, чтобы доказать это, извините.

Я хочу понять, является ли использование исключений вместо проверки правильным подходом в python (такого нет в большинстве языков, поэтому исключения так называются . ). В своем комментарии вы написали, что [вызов функции и перехват исключений, я полагаю] на самом деле более производительный, чем проверка существования метода , и мне хотелось бы знать, откуда у вас эта информация, вот и все .

@ashes999 ashes999 помимо факта облегченных исключений, это плохой признак — проверка существования метода не должна быть дольше, чем простая проверка переменной в памяти, в то время как исключения включали бы эту проверку , и над этим выполнялась некоторая другая работа ( нравится собирать описание) . Я предполагаю, что это была какая-то ошибка, и вы не должны полагаться на такую скорость.

В принципе это хорошо, и в Python, в отличие от других языков, есть культура «исключения как поток управления». Однако, если вы используете инструменты регистрации исключений, такие как Sentry / Raven или New Relic, такие исключения необходимо отфильтровывать по отдельности (если это возможно) или создавать шум. Я бы предпочел проверить, существует ли метод, а не вызывать его.

ОП спросил «Как проверить, существует ли метод в Python?» не «Как выполнить метод, который может не существовать?». Вы ответили на другой вопрос.

Это не правильно на многих уровнях. Сам метод может вызвать AttributeError, и это будет обнаружено, поскольку метод не существует! Это также разрушает поддержку отладчика для взлома исключений. Я также уверен, что это, вероятно, влияет на производительность, если все было в порядке. Последний, но не список. Я не хочу выполнять метод, просто проверьте, существует ли он. Вы должны рассмотреть возможность удаления этого ответа или, по крайней мере, поместить все эти предупреждения, чтобы наивные люди не вводили в заблуждение.

Проверьте, имеет ли класс такой метод?

hasattr(Dynamo, key) and callable(getattr(Dynamo, key)) 
hasattr(Dynamo, 'mymethod') and callable(getattr(Dynamo, 'mymethod')) 

Вы можете использовать self.__class__ вместо Dynamo

None них не может быть callable(getattr(Dynamo, ‘mymethod’, None)) , поэтому вы можете просто callable(getattr(Dynamo, ‘mymethod’, None)) . Я использовал этот ответ, потому что мой super (). Mymethod () мог бросить AttributeError

@sbutler Интересно, что это работает. Согласно PyCharm, подпись для getattr является def getattr(object, name, default=None): я подозреваю, что это не точно, потому что если бы это было так, я бы ожидал, что передача None в качестве третьего параметра не изменит поведение функции.

@bszom: В оболочке python help(getattr) говорит: «Когда задан аргумент по умолчанию, он возвращается, когда атрибут не существует; без него в этом случае возникает исключение». — (и действительно, вы можете проверить, что getattr действительно вызывает исключение, если атрибут отсутствует) настолько ясно, что бы PyCharm ни был, это неправильно.

@bszom Я обнаружил, что здесь обсуждается такое поведение getattr : stackoverflow.com/q/32499863/1545579

Вы можете попробовать использовать модуль ‘inspect’:

import inspect def is_method(obj, name): return hasattr(obj, name) and inspect.ismethod(getattr(obj, name)) is_method(dyn, 'mymethod') 

Может быть, так, если все методы вызываются

app = App(root) # some object call app att = dir(app) #get attr of the object att #['doc', 'init', 'module', 'button', 'hi_there', 'say_hi'] for i in att: if callable(getattr(app, i)): print 'callable:', i else: print 'not callable:', i 

Как насчет поиска в dyn.__dict__ ?

try: method = dyn.__dict__['mymethod'] except KeyError: print "mymethod not in dyn" 

Префикс с двойным подчеркиванием плюс суффикс с двойным подчеркиванием означает «это обычно используется самим интерпретатором Python», и обычно есть какой-то способ добиться того же эффекта от пользовательской программы для наиболее распространенных случаев использования (в этом случае это будет используя точечную нотацию для атрибута), но это не запрещено и не неправильно использовать его, если ваш вариант использования действительно требует этого.

Это не запрещено. Ошибочность субъективна: она зависит от того, насколько сильно вы хотите запутать программистов, придерживающихся соглашений: не используйте их, если у вас нет альтернативы.

Если ваш метод находится за пределами класса, и вы не хотите его запускать и создавать исключение, если оно не существует:

Я думаю, вам стоит посмотреть на пакет inspect . Это позволяет вам «обернуть» некоторые из вещей. Когда вы используете метод dir , он также отображает встроенные методы, унаследованные методы и все другие атрибуты, делающие возможными конфликты, например:

class One(object): def f_one(self): return 'class one' class Two(One): def f_two(self): return 'class two' if __name__ == '__main__': print dir(Two) 

Массив, который вы получаете из dir(Two) , содержит как f_one , так и f_two и множество встроенных файлов. С помощью inspect вы можете сделать это:

class One(object): def f_one(self): return 'class one' class Two(One): def f_two(self): return 'class two' if __name__ == '__main__': import inspect def testForFunc(func_name): ## Only list attributes that are methods for name, _ in inspect.getmembers(Two, inspect.ismethod): if name == func_name: return True return False print testForFunc('f_two') 

В этих примерах все еще перечислены оба метода в двух классах, но если вы хотите ограничить проверку только функцией в определенном классе, для этого требуется немного больше работы, но это абсолютно возможно.

Источник

Оцените статью