2010-03-11 8 views
2
try: 
    spam.foo 
except AttributeError: 
    do_somthing() 

(Разумно, чтобы проверить атрибут подобного не используя его?)В Python это хорошая практика?

+0

Если атрибут является свойством, а свойство имеет побочные эффекты, это может быть разрушительный. Зачем вам нужно знать, существует ли свойство? У вас есть источник. Почему бы не прочитать источник? –

ответ

13

Update:

Если вы действительно заинтересованы только в существует ли атрибут foo (а не делать что-то с атрибут), чем, конечно, hasattr() может быть лучшим способом проверки атрибута.
От разработчик/пользователь Точка зрения Я должен признаться, что для меня использование hasattr() лучше отражает ваше намерение. И, кроме того, что это приведет к уменьшению кода:

if not hasattr(spam,'foo'): 
    do_something() 

Документация hasattr() описывает, что она реализуется:

(Это реализуется), призывающую getattr(object, name) и видя вызывает ли это исключение или не.

Так что в основном hasattr() делает то же самое, что и вы. В этом случае я бы определенно пошел со встроенным решением, т. Е. hasattr(). Вы не получите преимущество в скорости.


Python призывает EAFP paradigm:

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

Так да это именно так, как следует это сделать если вы более или менее известно, что spam будет иметь атрибут foo большую часть времени (код будет (немного?) быстрее).
В противном случае, если spam не имеет атрибут foo (большую часть времени), то этот подход будет лучше:

if hasattr(spam, 'foo'): 
    bar = spam.foo 
else: 
    do_somthing() 

В разделе Википедии я связан описывает это. Цитата (где ЭСПЦ версия относится к тому, как вы написали свой образец кода):

Эти два образца кода имеют тот же эффект, хотя и будет разница в производительности. Когда спам имеет атрибут яйца, то EAFP образец будет бежать быстрее. Когда спам не имеет атрибута яйца («исключительный» случай), образец EAFP будет работать медленнее. (...) Если редкие случаи редко встречаются, то . Версия EAFP будет иметь превосходное среднее значение, чем альтернатива.

Что-то очевидно как (с помощью EAFP), вам не нужно каждый раз проверять объект перед тем, как вы захотите получить доступ к этому атрибуту.

+0

@felix Это все еще имеет место в моем случае (где я вообще не использую атрибут в контексте «try»)? Это все еще считается Pythonic? – orokusaki

+0

Я думаю, что 'try ... catch' - плохая идея. Избегайте их, если вы можете даже, если «проще просить прощения, чем разрешения». –

+0

@orokusaki: зачем вам это нужно, если вы не используете атрибут? Если вы тестируете, какой тип объекта он есть, то нет, это не считается Pythonic. Вместо этого типично использовать объект так, как вы надеялись использовать его, и обрабатывать любое исключение. Еще лучше изучите, почему у вас есть функция, которая использует различные объекты с разрозненными интерфейсами. – Kylotan

2

Лучше использовать

if hasattr(spam,"foo"): 
    #dosomthing with spam.foo 
else: 
    do_somthing() 

Python документы:

hasattr (объект, имя)
аргументы являются объектом и строка. Результат будет True, если строка является именем одного из атрибутов объекта , False, если нет. (Это осуществляется путем вызова GetAttr (объект, имя) и видя вызывает ли это исключение или нет.)

+1

Если вы хотите проверить 'spam.foo', вы должны использовать' hasattr (spam, "foo") '. 'hasattr (spam, foo)' предполагает, что 'foo' является переменной, содержащей строку, и проверяет' спам' для атрибута, названного строкой. –

+0

Ой! Смотрите, это исправлено. Спасибо Крису. –

+0

+1 для вашего ответа. Я выбрал ответ Феликса, потому что, если посетитель найдет этот вопрос, я думаю, для них важно понять оба угла. С его ответом теперь меньше «что использовать?» и больше «использовать интерфейс для стиля или использовать реализацию для скорости?». – orokusaki