Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 27, 2017 22:14:18

alemeor
Зарегистрирован: 2017-12-13
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Пояснение в ООП Python

Читал статью и не могу разобраться в одном моменте,поясните пожалуйста почему это так работает:
Есть такой код:

 class A:
    qux = "A"
    def __init__(self,name):
        self.name = name
    def foo(self):
        print('foo')
class B:
    qux = "B"
    def __init__(self):
        self.name = "B OBJECT"
    def bar(self):
        print('bar')
a = A('a')

 print(A is a.__class__)  #True
print(A == a.__class__)  #True
И если A то же самое, что a.__class__, то почему это выполняется по разному:

1)
 a.__class__ = B
a.bar #bar
2)
 A = B
a.bar #AttributeError: 'A' object has no attribute 'bar'
Почему во 2 случае bar нет в А

И второй момент:
1)
 a.__class__ = B
a = A('a')
Смог создать новый экземпляр
2)
 A = B
a = A()

А во втором случае могу создать новый экземпляр, не передавая значение атрибута в класс A, иначе возникает исключение: “2 аргумент передан”. Понятно, что этот атрибут получен из B. Но почему же тогда в 1 случае я должен передать значение атрибута, а во втором нет

Отредактировано alemeor (Дек. 27, 2017 22:14:38)

Офлайн

#2 Дек. 28, 2017 05:42:17

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Пояснение в ООП Python

alemeor
Почему во 2 случае bar нет в А
Потому что вы изменили класс “A”, но объект “а” уже создан, его класс не поменялся, у него остался старый класс. Питон - это такая странная штука, в питоне вообще все - объекты. Даже функции, даже классы. Переменная, которая хранит объект - это просто адрес ячейки памяти, с которой начинаются данные объекта. Когда вы пишите вот такое

 a = Foo()
a = Bar()
вы в первой строке выделяете в памяти место, достаточное для хранения объектов типа Foo, заполняете это место какими-то данными (значениями полей объекта) и присваиваете переменной “а” значение адреса этой памяти.
Во второй строке вы создаете новый объект, и присваиваете “а” новое значение адреса. В памяти у вас теперь два объекта, но объект, который вы создали в первой строке больше не используется, поэтому Сборщик Мусора его вскоре уничтожит, а память очистит.

 A = B
a.bar 
У вас был класс А - это тоже объект (объект значение которого - класс), у него есть адрес, а переменная А хранит этот адрес. Потом вы сделали A = B, присвоили этой переменной новый адрес. Но что станет с объектом-классом в памяти по старому адресу? А он никуда не денется, его использует переменная а (a.__class__), поэтому Сборщик Мусора не будет его удалять, и он по-прежнему будет храниться в a.__class__.

 a.__class__ = B
a = A('a')
второй строкой вы создаете новую переменную, а не присваиваете значение старой.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version