Меня смущают различия следующих кодов:
class car:
def __init__(self, weight):
self.weight = weight
class car:
def __init__(self, weight):
self.weight = 0
class car:
def __init__(self, weight=0):
self.weight = weight
class car:
def __init__(self, weight=0):
self.weight = 0
class car:
def __init__(self, weight=0):
self.weight = 1
class car:
def __init__(self):
self.weight = 0
Насколько я понимаю, если я укажу weight=0
в def __init__(self, weight=0)
, то атрибуты по умолчанию будут равны 0. Но кажется, что я также могу сделать то же самое, если не укажу def __init__(self, weight)
, а добавлю self.weight = 0
потом. Какая разница? Что, если мы дадим два разных значения?
🤔 А знаете ли вы, что...
Python подходит для начинающих программистов благодаря своей простоте и читаемости кода.
Вы запутались в понятиях функции arg, значения по умолчанию для arg и переменной-члена, вы просто слишком их смешиваете.
Аргумент функции
Для
def __init__(self,weight)
вы ожидаете, что при вызове конструктора будет передана переменная, которой присвоено имя «вес». Это аргумент функции.
Значение по умолчанию для аргумента функции
Для def __init__(self,weight=0)
вы все еще ожидаете передачи переменной, но все в порядке, если она отсутствует, и в этом случае значение по умолчанию 0 будет просто присвоено символу «вес». Это значение по умолчанию для аргумента функции.
Атрибут участника
Теперь о коде ниже:
class car:
def __init__(self, weight=0):
self.weight = weight
Фактически это означает: передайте мне переменную, я присвою ее символу «вес», в противном случае я присвою этому символу 0. И я присвою значение символа «вес» «self.weight», они находятся в совершенно разных областях и, следовательно, являются разными символами. Это не похоже на C++, когда вы выполняете почленную инициализацию. «self.weight» — атрибут экземпляров класса.
вес против собственного веса
Будем надеяться, что теперь, приведя последний пример, логика будет достаточно ясна:
class car:
def __init__(self, weight=0):
self.weight = 1
Здесь вы получаете символ с именем «вес», независимо от того, по умолчанию он или передан, он просто игнорируется, т. е. никуда не ссылается, вместо этого вы присваиваете 1 переменной-члену self.weight.
class car:
def __init__(self, weight):
self.weight = weight
weight
(т. е. нельзя вызвать только my_car = car()
). И какое бы значение weight
ни было передано при создании объекта, оно будет присвоено его атрибуту weight
:>>> my_car = car()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: car.__init__() missing 1 required positional argument: 'weight'
>>> my_car = car(weight=69)
>>> print(my_car.weight)
69
class car:
def __init__(self, weight):
self.weight = 0
weight
. Но независимо от того, какое значение weight
передается при инициализации объекта, оно будет 0
:>>> my_car = car()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: car.__init__() missing 1 required positional argument: 'weight'
>>> my_car = car(weight=69)
>>> print(my_car.weight)
0
>>> my_car.weight = 69
>>> print(my_car.weight)
69
class car:
def __init__(self, weight=0):
self.weight = weight
weight
является необязательным аргументом (т. е. передавать не нужно, но можно передать). Если weight
не передан в качестве аргумента, ему будет присвоено значение по умолчанию, в данном случае 0
:>>> my_car = car()
>>> print(my_car.weight)
0
>>> my_car = car(weight=69)
>>> print(my_car.weight)
69
class car:
def __init__(self, weight=0):
self.weight = 0
weight
не является обязательным. Но что интересно в этом; независимо от того, какое значение weight
передается в качестве аргумента или каково его значение по умолчанию, оно всегда будет 0
при создании объекта:>>> my_car = car() # No errors..
>>> print(my_car.weight)
0
>>> my_car = car(weight=69) # Useless argument..
>>> print(my_car.weight)
0
class car:
def __init__(self, weight=0):
self.weight = 1
weight
является необязательным, и независимо от того, какое значение по умолчанию имеет weight
или что передается в качестве аргумента при создании объекта, weight
будет присвоено значение 1
:>>> my_car = car()
>>> print(my_car.weight)
1
>>> my_car = car(weight=69)
>>> print(my_car.weight)
1
class car:
def __init__(self):
self.weight = 0
weight
будет присвоено значение 0
:>>> my_car = car(69)
# That positional argument is `self`... 🙂
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: car.__init__() takes 1 positional argument but 2 were given
>>> my_car = car(weight=69)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: car.__init__() got an unexpected keyword argument 'weight'
>>> my_car = car()
>>> print(my_car.weight)
0
Хорошо, так какой из них хорош или какой вам следует использовать? На мой взгляд (вы можете не согласиться), третий хорош/лучше(?), но с небольшими изменениями:
class car:
def __init__(self, weight):
self.weight = weight
ПОЧЕМУ?
weight
в качестве аргумента, иначе выдаст ошибку.0
..Кроме того, следуйте «Соглашению CapWords» для названий классов. 🙂
🫡