функциональная разница между экземпляром и объектом, созданным не через init?
зачем нужен метод init вместе в class-ом?
Ответы (3 шт):
Магический метод __init__ запускается при создании экземпляра класса. Пример:
class A():
def __init__(self):
print('Hello, world!')
a = A()
out:
Hello, world!
self
Слово self используется для обозначения экземпляра класса.
Используя ключевое слово self, мы получаем доступ к атрибутам и методам класса в Python.
__init__ method
__init__ - это метод в классах Python.
В объектно-ориентированной терминологии он называется конструктором.
Этот метод вызывается, когда объект создается из класса,
и позволяет классу инициализировать атрибуты класса.
# Узнайте стоимость прямоугольного поля
class Rectangle:
def __init__(self, length, breadth, unit_cost=0):
self.length = length
self.breadth = breadth
self.unit_cost = unit_cost
def get_area(self):
return self.length * self.breadth
def calculate_cost(self):
area = self.get_area()
return area * self.unit_cost
# breadth = 120, length = 160, 1 sq unit cost = 2000 руб.
rectangle = Rectangle(160, 120, 2000)
print(f"Площадь прямоугольника: {rectangle.get_area()}")
__init__ вызывается уже после создания экземпляра класса, а не во время, в примере ниже видно что сначала выполнится print(1, ob), и лишь затем print(2, self), причем объект экземпляра класса создан уже до вызова __init__, и затем просто передается ему в аргумента в self
class A():
def __new__(cls, *args, **kwargs):
ob = super().__new__(cls)
print(1, ob)
return ob
def __init__(self):
print(2, self)
a = A()
# 1 <__main__.A object at 0x000002487C6CD2E0>
# 2 <__main__.A object at 0x000002487C6CD2E0>
в примере ниже видно, что __init__ необязательный метод, и атрибуты класса можно создавать где угодно и когда угодно, хотя это конечно и считается неправильным подходом
class A():
def test(self):
self.b = 123
a = A()
a.test()
print(a.b) # 123
в примере ниже видно, что self это не ключевое слово, это просто обычный аргумент у метода и его общепринятое название, но это аргумент который идет первым, ничто не мешает нам назвать его иначе, хотя это конечно и считается неправильным подходом
class A():
def __init__(qwerty):
qwerty.b = 123
a = A()
print(a.b) # 123
в примере ниже видно, что в исходном классе A, все его методы print(A.test) это обычные функции (function), которые лежат в области видимоcти A, а все методы его объекта a print(a.test) это методы(method), которые лежат в новой области видимости a,
причем эти методы, это просто специально "декорированные" исходные функции объекта A print(a.test.__func__), "декорирование" которых придает функционал необязательности указания первого аргумента self при вызове методов как a.test(123), причем нам ничего не мешает обращаться к методу и через исходную функцию A.test(a, 123), но уже передавая первый аргумент self
class A():
b = 321
def test(self, v):
print(v)
print(A.test) # <function A.test at 0x000002AC72E35F70>
a = A()
print(a.test) # <bound method A.test of <__main__.A object at 0x000002AC72FE5790>>
print(a.test.__func__) # <function A.test at 0x000002AC72E35F70>
a.test(123) # 123
A.test(a, 123) # 123