В чем разница этих двух записей кода, объясните новичку попроще

Учу ООП и на уроках нас учат, что для того, чтобы вывести на экран значения локальных свойств экземпляра класса, необходимо создать дополнительный метод, и выглядит это вот так:

class Point:
    def set(self, x, y):
        self.x = x
        self.y = y

    def get(self):
        return (self.x, self.y)

p = Point()
p.set(1, 2)
print(p.get())

Но почему бы не вывести значения свойств через дополнительный объект класса, так запись будет проще?

class Point:
    def set(self, x, y):
        return x, y

p = Point()
е = p.set(1, 2)
print(e)

В чем разница этих записей и как правильно?


Ответы (2 шт):

Автор решения: Эникейщик

В первом варианте

def set(self, x, y):
    self.x = x
    self.y = y

значения x и y присваиваются свойствам экземпляра класса. После этого в свойствах экземпляра p.x и p.y хранятся указанные значения.

В втором варианте

def set(self, x, y):
    return x, y

ничего никуда не присваивается и вообще эта функция по сути ничего не делает.

Аналогия: в первом варианте функция set() кладет в левый и правый карманы ваших брюк x и y конфет. А функция get() сообщает потом сколько конфет в каком кармане лежит, конфеты там остаются лежать и можно с ними делать все, что угодно. Во втором варианте вы никакие конфеты никуда не кладете, а функция set() просто сообщает, сколько конфет кто-то хотел бы положить в карманы, но не положил.


почему бы не вывести значения свойств через дополнительный объект класса

В вашем коде нет никакого "дополнительного объекта класса".

→ Ссылка
Автор решения: Dmitry

Попробую описать на примере кода

class Point:
    def set(self, x, y):
        self.x = x
        self.y = y
    def get(self):
        return (self.x, self.y)
    def set_incorrect(self, x, y):
        return x, y

установим значения в экземпляр класса

p = Point()
p.set(1,2)
print(type(p), p.x, p.y)

Вывод

<class '__main__.Point'> 1 2

все верно p - это экземпляр класса Point

Если воспользоваться вашим вариантом, то можно увидеть, что объект не изменится и смысла в таком использовании нет

p = Point()
p.set(1,2)
e = p.set_incorrect(10000, 20000)
print(f"это возврат не корректного метода {e}\nс типом данных {type(e)}")
print(f"а это хранит объект p {p.x, p.y}\nс типом данных {type(p)}")

Вывод

это возврат не корректного метода (10000, 20000)
с типом данных <class 'tuple'>
а это хранит объект p (1, 2)
с типом данных <class '__main__.Point'>

Заключение. В реализации парадигм ООП обязательное использование обращения к полям и методам внутри класса через self. Иначе нет необходимости писать классы и можно использовать функциональный подход.

→ Ссылка