Руководство по использованию различных типов переменных в классе python?

66
8

Я потратил некоторое время на поиск руководства о том, как решить, как хранить данные и функции в классе python. Я должен указать, что я новичок в ООП, поэтому такие ответы, как:

атрибуты данных соответствуют "переменным экземпляра" в Smalltalk и "членам данных" в C++. (см. http://docs.python.org/tutorial/classes.html

Оставьте меня почесывать голову. Я полагаю, что то, что мне нужно, - это праймер на ООП, предназначенный для программистов на питоне. Я хотел бы надеяться, что руководство/праймер также включит какой-то глоссарий или определения, поэтому после прочтения я мог бы разумно говорить о различных доступных типах переменных. Я хочу понять мыслительные процессы, решающие, когда использовать формы a, b, c и d в следующем коде.

class MyClass(object):
a = 0

def __init__(self):
b = 0
self.c = 0
self.__d = 0

def __getd(self):
return self.__d

d = property(__getd, None, None, None)

спросил(а) 2021-01-19T19:04:27+03:00 9 месяцев, 1 неделя назад
1
Решение
79

a, b и c показывают различные области переменных. Значит, эти переменные имеют различную видимость и среду, в которой они действительны.

Сначала вам нужно понять разницу между классом и объектом. Класс - это средство описания какого-либо общего поведения. Затем создается объект на основе этого класса. Объекты "наследуют" все методы класса и могут определять переменные, привязанные к объекту. Идея состоит в том, что объекты инкапсулируют некоторые данные и требуемое поведение для работы над этими данными. Это основное отличие от процедурного программирования, когда модули просто определяют поведение, но не данные.

c - теперь такая переменная экземпляра, означающая переменную, которая живет в области экземпляра MyClass. self всегда является ссылкой на текущий экземпляр объекта, в котором работает текущий код. Технически __d работает так же, как c и имеет тот же объем. Разница здесь в том, что в Python существует соглашение о том, что переменные и методы, начинающиеся с двух символов подчеркивания, считаются частными, не должны использоваться кодом вне класса. Это необходимо, потому что у Python нет способа определить действительно частные или защищенные методы и переменные, как это делают многие другие языки.

b - простая переменная, которая действительна только в методе __init__. Если выполнение оставляет метод __init__, переменная b собирается собирать мусор и больше не доступна, а c и __d остаются в силе. Заметим, что b не добавляется к self.

Теперь a определяется непосредственно в классе. Это делает его так называемой переменной класса. Как правило, он используется для хранения статических данных. Эта переменная одинакова для всех экземпляров класса MyClass.

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

ответил(а) 2021-01-19T19:04:27+03:00 9 месяцев, 1 неделя назад
66

а. для переменных, разделяемых всеми экземплярами MyClass б. для переменной, которая будет существовать только внутри функции init. с. является атрибутом конкретного экземпляра MyClass и является частью внешнего интерфейса MyClass (т.е. не удивляйтесь, если какой-нибудь другой программист галошит эту переменную). Недостаток использования "c" заключается в том, что он уменьшает вашу гибкость, чтобы вносить изменения в MyClass (в какой-то момент кто-то, вероятно, будет полагаться на то, что "c" существует и делает определенные вещи, поэтому, если вы решите реорганизовать свою класса, вам нужно быть готовым сохранить "c" навсегда). __d. является атрибутом конкретного экземпляра MyClass и является частью внутренней реализации MyClass; можно предположить, что только код MyClass будет читать/записывать этот атрибут. д. Делает __d во многом похожим на c. Однако преимущество использования d с __d состоит в том, что, если, например, d() может быть вычислен из некоторого другого атрибута, можно было бы исключить дополнительное хранение __d. Кроме того, вы гарантируете, что это только чтение извне, а не внешнее.

ответил(а) 2021-01-19T19:04:27+03:00 9 месяцев, 1 неделя назад
65

Популярная онлайн-книга, которая широко рекомендуется, - это погружение в Python. См. Главу 5.

Что касается ваших вопросов:

    a - переменная класса (идентична для всех объектов этого класса).

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

    c, d - переменные экземпляра (каждый объект может иметь разные значения); и их различная семантика означает:

    c - обычная переменная экземпляра, которая может быть прочитана или записана как object.c (класс не определяет геттер или сеттер для нее) __d является частной переменной, доступной только для чтения и предназначенной для доступа через функцию getter getd(); его строка свойств показывает, что у него нет setter setd(), следовательно, его нельзя изменить. Префикс с двойным подчеркиванием __ означает, что он является внутренним и не предназначен для доступа к чему-либо вне класса. d - это свойство, которое позволяет (только для __d) доступ к __d, но, как указывает Майкл, без необходимости хранения дополнительной переменной, и его можно вычислить динамически при вызове getd().

ответил(а) 2021-01-19T19:04:27+03:00 9 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема