У меня проблемы с пониманием инициализации классов.
В чем их смысл и как мы узнаем, что в них включить? Требует ли написание в классах другого типа мышления по сравнению с созданием функций (я решил, что могу просто создать функции, а затем просто обернуть их в класс, чтобы я мог использовать их повторно. Будет ли это работать?)
Вот пример:
class crawler:
# Initialize the crawler with the name of database
def __init__(self,dbname):
self.con=sqlite.connect(dbname)
def __del__(self):
self.con.close()
def dbcommit(self):
self.con.commit()
Или другой пример кода:
class bicluster:
def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
self.left=left
self.right=right
self.vec=vec
self.id=id
self.distance=distance
Есть так много классов, с которыми __init__
я сталкиваюсь, пытаясь прочитать чужой код, но я не понимаю логики их создания.
Ответы:
Из того, что вы написали, вы упускаете важный элемент понимания: разницу между классом и объектом.
__init__
не инициализирует класс, он инициализирует экземпляр класса или объекта. У каждой собаки есть окрас, а у собак как класс - нет. У каждой собаки четыре или меньше лап, но у класса собак нет. Класс - это концепция объекта. Когда вы видите Фидо и Спот, вы узнаете их сходство, их собачью натуру. Это класс.Когда ты говоришь
Вы говорите, что Фидо - коричневая собака с 4 ногами, а Спот немного калека и в основном желтого цвета.
__init__
Функция вызывается конструктор, или инициализатор, и автоматически вызывается при создании нового экземпляра класса. В этой функции вновь созданный объект назначается параметруself
. Обозначениеself.legs
- это атрибут, вызываемыйlegs
объектом в переменнойself
. Атрибуты похожи на переменные, но они описывают состояние объекта или определенные действия (функции), доступные для объекта.Однако обратите внимание, что вы не устанавливаете
colour
само собачье достоинство - это абстрактное понятие. Есть атрибуты, которые имеют смысл для классов. Например,population_size
одна такая - считать Фидо не имеет смысла, потому что Фидо всегда один. Считать собак имеет смысл. Допустим, в мире 200 миллионов собак. Это собственность класса Dog. Ни Фидо, ни Спот не имеют отношения к числу 200 миллионов. Он называется «атрибутом класса», в отличие от «атрибутов экземпляра», которые естьcolour
илиlegs
выше.Теперь о чем-то менее собачьем и более связанном с программированием. Как я пишу ниже, класс для добавления вещей не имеет смысла - что это за класс? Классы в Python состоят из наборов разных данных, которые ведут себя одинаково. Класс собак состоит из Фидо и Спота и 199999999998 других похожих на них животных, все они писают на фонарные столбы. Из чего состоит класс для добавления вещей? Какими присущими им данными они отличаются? И какие действия они разделяют?
Однако числа ... это более интересные предметы. Скажем, целые числа. Их много, намного больше, чем собак. Я знаю, что в Python уже есть целые числа, но давайте поиграемся в глупости и снова «реализуем» их (обманывая и используя целые числа Python).
Итак, целые числа - это класс. У них есть некоторые данные (значение) и поведение («добавьте меня к этому другому числу»). Покажем это:
Это немного хрупко (мы предполагаем, что
other
это будет MyInteger), но сейчас мы проигнорируем. В реальном коде мы бы этого не сделали; мы бы проверили его, чтобы убедиться, и, может быть, даже принудили его («вы не целое число? черт возьми, у вас есть 10 наносекунд, чтобы стать одним! 9 ... 8 ....»)Мы могли даже определять дроби. Дроби тоже умеют складывать себя.
Дробей даже больше, чем целых чисел (не совсем, но компьютеры этого не знают). Сделаем два:
На самом деле вы здесь ничего не декларируете. Атрибуты подобны переменным нового типа. Нормальные переменные имеют только одно значение. Допустим, вы пишете
colour = "grey"
. Вы не можете иметь другую переменнуюcolour
, которая"fuchsia"
- не в том же месте в коде.В определенной степени это решают массивы. Если вы скажете
colour = ["grey", "fuchsia"]
, что вы сложили два цвета в переменную, но вы различаете их по их положению (в данном случае 0 или 1).Атрибуты - это переменные, привязанные к объекту. Как и в случае с массивами, у нас может быть много
colour
переменных для разных собак . Итак,fido.colour
это одна переменная, аspot.colour
это другая. Первый привязан к объекту внутри переменнойfido
; второйspot
,. Теперь, когда вы вызываетеDog(4, "brown")
, orthree.add(five)
, всегда будет невидимый параметр, который будет назначен дополнительному висящему в начале списка параметров. Он называется условноself
и получает значение объекта перед точкой. Таким образом, внутри объекта Dog__init__
(конструктора)self
будет то, чем окажется новый Dog; вMyInteger
«сadd
,self
будет привязан к объекту в переменнойthree
. Таким образом,three.value
будет той же переменной внеadd
, что иself.value
внутриadd
.Если я скажу
the_mangy_one = fido
, я начну ссылаться на объект, известный какfido
с еще одним именем. С этогоfido.colour
момента это точно такая же переменная, какthe_mangy_one.colour
.Итак, вещи внутри
__init__
. Вы можете думать о них как о записях в свидетельстве о рождении Собаки.colour
сама по себе является случайной величиной, может содержать что угодно.fido.colour
илиself.colour
похож на поле формы в идентификационной карточке собаки; и__init__
клерк заполняет его впервые.Есть более ясный?
РЕДАКТИРОВАТЬ : расширение комментария ниже:
Вы имеете в виду список объектов , не так ли?
Во-первых,
fido
на самом деле это не объект. Это переменная, которая в настоящее время содержит объект, точно так же, как вы говоритеx = 5
,x
что это переменная, в настоящее время содержащая число пять. Если вы позже передумаете, вы можете это сделатьfido = Cat(4, "pleasing")
(при условии, что вы создали классCat
), иfido
с этого момента он будет «содержать» объект cat. Если вы это сделаетеfido = x
, он будет содержать цифру пять, а вовсе не объект животного.Класс сам по себе не знает своих экземпляров, если вы специально не напишете код для их отслеживания. Например:
Вот
census
атрибутCat
класса уровня класса.Учтите, что вы не получите
[fluffy, sparky]
. Это просто имена переменных. Если вы хотите, чтобы у самих кошек были имена, вы должны создать отдельный атрибут для имени, а затем переопределить__str__
метод, чтобы вернуть это имя. Назначение этого метода (т.е. функции, связанной с классом, какadd
или__init__
) - описать, как преобразовать объект в строку, например, когда вы ее распечатываете.источник
Чтобы вложить свои 5 центов в подробное объяснение от Амадана .
Где классы - это абстрактное описание «типа». Объекты - это их реализации: живое дышащее существо. В объектно-ориентированном мире есть принципиальные идеи, которые можно назвать сущностью всего. Они есть:
У объектов есть одна или несколько характеристик (= Атрибуты) и поведения (= Методы). Поведение во многом зависит от характеристик. Классы в общих чертах определяют, что должно выполнять поведение, но до тех пор, пока класс не реализован (не создан) как объект, он остается абстрактным понятием возможности. Разрешите проиллюстрировать это с помощью «наследования» и «полиморфизма».
Некоторые характеристики определяют людей. Но все национальности чем-то отличаются. Так что "национальные типы" - это своего рода Люди с статистами. «Американцы» являются типом «людей» и наследуют некоторые абстрактные характеристики и поведение от человеческого типа (базового класса): это наследование. Все люди могут смеяться и пить, поэтому все детские классы тоже могут! Наследование (2).
Но поскольку все они одного вида (Тип / базовый класс: Люди), вы можете иногда их менять: см. Цикл for в конце. Но они выявят индивидуальную характеристику, а именно полиморфизм (3).
Итак, у каждого человека есть любимый напиток, но представители всех национальностей склонны к особому виду напитка. Если вы подклассифицируете национальность из типа людей, вы можете перезаписать унаследованное поведение, как я продемонстрировал выше с помощью
drink()
метода. Но это все еще на уровне класса, и поэтому это все еще обобщение.создает экземпляр класса German, и я "изменил" характеристику по умолчанию в начале. (Но если вы назовете hans.drink ('Milk'), он все равно напечатает «Мне нужно больше пива» - очевидная ошибка ... или, может быть, это то, что я бы назвал функцией, если бы я был сотрудником более крупной компании. ;-)! )
Характеристики типа, например, Germans (hans), обычно определяются через конструктор (в python:)
__init__
в момент создания экземпляра. Это момент, когда вы определяете класс, который станет объектом. Вы можете сказать «вдохнуть жизнь» в абстрактное понятие (класс), наполнив его индивидуальными характеристиками и став объектом.Но поскольку каждый объект является экземпляром класса, они разделяют все основные типы характеристик и поведение. Это главное преимущество объектно-ориентированной концепции.
Чтобы защитить характеристики каждого объекта, вы их инкапсулируете - это означает, что вы пытаетесь связать поведение и характеристику и затрудняете манипулирование им извне объекта. Это инкапсуляция (1)
источник
Это просто инициализация переменных экземпляра.
Например, создайте
crawler
экземпляр с определенным именем базы данных (из приведенного выше примера).источник
left=None
left будет инициализирован,None
если при созданииleft
параметр не указан.left = foo
сработает - один раз. Смысл занятий в том, чтобы делать что-то разумное для каждогоcrawler
. Классы - это не функции и не что-то, что можно сравнить с функциями (ну, пока вы не станете намного более продвинутыми и не войдете в функциональное программирование, но теперь это вас просто запутает). Прочтите мой ответ о том, что такое классы на самом деле - вы все еще не понимаете.Похоже, вам нужно использовать
__init__
Python, если вы хотите правильно инициализировать изменяемые атрибуты ваших экземпляров.См. Следующий пример:
Это совсем другое дело в Java, где каждый атрибут автоматически инициализируется новым значением:
дает результат, который мы интуитивно ожидаем:
Но если вы объявите
attr
asstatic
, он будет действовать как Python:источник
Следуя вашему примеру с автомобилем : когда вы получаете машину, вы просто не получаете случайную машину, я имею в виду, вы выбираете цвет, марку, количество мест и т. Д. И некоторые вещи также "инициализируются" без вашего выбора для него, например, количество колес или регистрационный номер.
Итак, в
__init__
методе, который вы определяете атрибуты создаваемого экземпляра. Итак, если нам нужен синий автомобиль Renault для 2 человек, мы должны инициализировать или создать что-тоCar
вроде:Таким образом, мы создаем экземпляр
Car
класса. Это__init__
тот, который обрабатывает наши конкретные атрибуты (например,color
илиbrand
) и генерирует другие атрибуты, напримерregistration_number
.__init__
методеисточник
Классы - это объекты с атрибутами (состояние, характеристика) и методами (функции, возможности), которые специфичны для этого объекта (например, белый цвет и сила полета, соответственно, для утки).
Создавая экземпляр класса, вы можете придать ему некоторую начальную индивидуальность (состояние или характер, например имя и цвет платья новорожденного). Вы делаете это с помощью
__init__
.Обычно
__init__
автоматически устанавливает характеристики экземпляра при вызовеinstance = MyClass(some_individual_traits)
.источник
__init__
Функция установки всех переменных - членов в классе. Итак, как только ваш бикластер создан, вы можете получить доступ к члену и вернуть значение:Ознакомьтесь с документацией Python для получения некоторой информации. Вы захотите взять книгу по концепциям объектно-ориентированного программирования, чтобы продолжить обучение.
источник
В приведенном выше примере мы используем виды как глобальные, так как они всегда будут одинаковыми (можно сказать, как константа). когда вы вызываете
__init__
метод,__init__
будут инициированы все переменные внутри (например: порода, имя).если вы распечатаете приведенный выше пример, позвонив ниже, как это
Это означает, что он будет инициализирован только во время создания объекта. поэтому все, что вы хотите объявить постоянным, сделайте его глобальным, а все, что меняет, использует
__init__
источник