«Существует еще третий класс для компоновки элементов» — еще и четверный (QBoxLayout), и пятый (QFormLayout), и шестой (QStackedLayout) :)
Вообще статья стала бы более читабельной, если бы короткие пояснения о том, что делается в каждой строке кода были не отдельным текстом, а как комментарии в самом коде. Не очень удобно после каждого предложения перемещаться обратно к кода.
Я не против самописных алгоритмов :) Я к тому, что они не всегда сразу получаются оптимальными, поэтому если что-то тормозит, то это в первую очередь будет алгоритм, а не метод доступа к атрибутам (про использование dir я даже не думаю :)
Угу, __getattribute__ вызывается при обращении к любым атрибутам, __dict__ в том числе, поэтому первая попытка собственной реализации __getattribute__ обычно заканчивается бесконечной рекурсией :)
getattr(obj, attr_name, None) удобно использовать когда нет разницы между отсутствием атрибута и равенством атрибута None.
А вообще, практика показывает, что очень часто, оптимизация кода типа проверка наличия атрибута через getattr и Exception или поиск в __dict__, практически не дает выигрыша в скорости, так как проблемы кроются в самописных алгоритмах или кривости архитектуры :)
Да, согласен, обращение к атрибуту «напрямую» и есть поиск в __dict__. Но в первом случае должно работать быстрее из-за меньшего количества дополнительных действий, как то получение самого __dict__. Я не утверждаю, а предполагаю.
То, что hasattr реализован через getattr и исключения можно увидеть в доке: «This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.» При наличие атрибута это видно из тестов test_exc_getattr_true_this_ca и test_hasattr_true_this_ia. Но непонятно, почему так отличается результат в случае отсутствия атрибута (test_hasattr_false и test_hasattr_false).
Самый первый вопрос: стоит ли шкурка вычинки? Стоило ли проделывать такое количество работы ради получения очевидных результатов? Помоему достаточно иметь общее представление о затратах на каждый из методов.
__dict__ — поиск значения в ассоциативном массиве. Что может быть быстрее? Только прямое обращение к атрибуту, если он есть (в противном случае получим «медленное» исключение).
hasattr — реализован через getattr и исключения. Тогда очевидно, что по времени затраты будут примерно такие же как и на отдельную проверку getattr с отловом исключения (при наличие атрибута — быстро, при отсутствие — медленно).
dir — достаточно оценить время выполнения этой функции и сравнить с поиском в ассоциативном массиве.
Вот и получается, что прямой доступ (при наличии атрибута) и __dict__ — самые быстрые методы. dir — сама по себе медленная функция. В остальных случаях, будут выскакивать и ловиться исключения, а это «тяжелый» и медленный механизм. Поэтому, единственное, что заслуживает внимание — это сравнение dir и случаев с исключениями.
Кстати, а как на счет getattr(obj, attr_name, None)? Имхо, если атрибут не найден, это должно работать быстрее, чем бросать исключение.
Но в любом случае, наглядные результаты всегда надежней, чем сухая теория :)
Результат результату рознь. Обычно все хотят получить результат здесь и сейчас, и это, как упомянул автор, «позволяет бросаться грудью на амбразуру, решать проблемы разрубая их как гордиев узел». Именно поэтому мы сначала делаем, а потом думаем. И именно поэтому, получение результата занимает намного больше времени, чем нам хотелось (из-за спешки и «недумания»).
Есть еще результат, который можно получить в долгосрочной перспективе. Такой результат получается если следовать принципу «семь раз отмерь, а один отрежь».
Можно неделю сидеть и думать, а потом сделать за час. А можно неделю работать в поте лица, а потом месяц переделывать. И проблема в том, что не редко начальство больше любит последний вариант…
QFormLayout - что-то типа частного случаю грида. Из названия понятно, что его можно использовать для создания форм ввода данных, поэтому у него только 2 колонки - label (описывает чего вводится) и контрол (например, эдитор). Преимущество относительно грида - простота использования:
formLayout = QFormLayout()
formLayout.addRow("&Login:", loginEdit)
formLayout.addRow("&Pasw:", paswEdit)
self.setLayout(formLayout)
QGridLayout'ом можно сделать тоже самое:
gridLayout = QGridLayout()
gridLayout.addWidget(QLabel('Login'), 0, 0)
gridLayout.addWidget(loginEdit, 0, 1)
gridLayout.addWidget(QLabel('Pasw'), 1, 0)
gridLayout.addWidget(paswEdit, 1, 1)
self.setLayout(gridLayout)
Вообще статья стала бы более читабельной, если бы короткие пояснения о том, что делается в каждой строке кода были не отдельным текстом, а как комментарии в самом коде. Не очень удобно после каждого предложения перемещаться обратно к кода.
getattr(obj, attr_name, None) удобно использовать когда нет разницы между отсутствием атрибута и равенством атрибута None.
А вообще, практика показывает, что очень часто, оптимизация кода типа проверка наличия атрибута через getattr и Exception или поиск в __dict__, практически не дает выигрыша в скорости, так как проблемы кроются в самописных алгоритмах или кривости архитектуры :)
То, что hasattr реализован через getattr и исключения можно увидеть в доке: «This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.» При наличие атрибута это видно из тестов test_exc_getattr_true_this_ca и test_hasattr_true_this_ia. Но непонятно, почему так отличается результат в случае отсутствия атрибута (test_hasattr_false и test_hasattr_false).
__dict__ — поиск значения в ассоциативном массиве. Что может быть быстрее? Только прямое обращение к атрибуту, если он есть (в противном случае получим «медленное» исключение).
hasattr — реализован через getattr и исключения. Тогда очевидно, что по времени затраты будут примерно такие же как и на отдельную проверку getattr с отловом исключения (при наличие атрибута — быстро, при отсутствие — медленно).
dir — достаточно оценить время выполнения этой функции и сравнить с поиском в ассоциативном массиве.
Вот и получается, что прямой доступ (при наличии атрибута) и __dict__ — самые быстрые методы. dir — сама по себе медленная функция. В остальных случаях, будут выскакивать и ловиться исключения, а это «тяжелый» и медленный механизм. Поэтому, единственное, что заслуживает внимание — это сравнение dir и случаев с исключениями.
Кстати, а как на счет getattr(obj, attr_name, None)? Имхо, если атрибут не найден, это должно работать быстрее, чем бросать исключение.
Но в любом случае, наглядные результаты всегда надежней, чем сухая теория :)
Есть еще результат, который можно получить в долгосрочной перспективе. Такой результат получается если следовать принципу «семь раз отмерь, а один отрежь».
Можно неделю сидеть и думать, а потом сделать за час. А можно неделю работать в поте лица, а потом месяц переделывать. И проблема в том, что не редко начальство больше любит последний вариант…
formLayout = QFormLayout()
formLayout.addRow("&Login:", loginEdit)
formLayout.addRow("&Pasw:", paswEdit)
self.setLayout(formLayout)
QGridLayout'ом можно сделать тоже самое:
gridLayout = QGridLayout()
gridLayout.addWidget(QLabel('Login'), 0, 0)
gridLayout.addWidget(loginEdit, 0, 1)
gridLayout.addWidget(QLabel('Pasw'), 1, 0)
gridLayout.addWidget(paswEdit, 1, 1)
self.setLayout(gridLayout)