@Intel1000

В чем разница между параметрами и атрибутами классов?

class Person:

      def __init__(self, name):
            self.name=name
            self.age=1
 

tom=Person('tom')

print(tom.name)
print(tom.age)
tom.age=37
print(tom.age)


Параметр name в методе __init__ и атрибут name, прописанный под ним. Разве это не одно и тоже, или есть разница? Ведь тогда age тоже должен быть прописан в методе в скобках после name.
  • Вопрос задан
  • 1981 просмотр
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Параметры метода относятся только к самому методу. Остальной класс про них знает, но только в плане "что нужно передать этому методу при вызове". Как метод использует тот или иной параметр - это его дело.

Атрибуты класса привязаны к экземпляру класса. По сути, у большинства объектов есть скрытый словарь __dict__, который хранит атрибуты этого объекта. Создание атрибута означает внесение записи в __dict__.

Как атрибуты создаются - определяется в первую очередь конструктором класса, т.е. методом __init__(), хотя и не только им. Обычно можно создать атрибут в любой момент времени, хотя это не рекомендуется делать, так как это запутывает программу.

При этом у __init__() есть полная свобода действий в плане того, откуда брать значения для атрибутов класса и какие атрибуты создавать. Пример:
class Point:
    def __init__(self):
        self.x = 0
        self.y = 0

point = Point()
# у point есть два собственных атрибута, x и y
print(point.__dict__)  # {'x': 0, 'y': 0}

Здесь конструктор не принимает параметров, так как он использует константы для создания атрибутов.
Он также мог бы брать значения атрибутов из собственных параметров, мог бы иметь параметры, которые не относятся к атрибутам, или всё сразу в любой комбинации.

Пример параметров, не относящихся к атрибутам:
class Point:
    def __init__(self, is_3d):
        self.x = 0
        self.y = 0
        if is_3d:  # этот параметр не используется как значение атрибута
            self.z = 0  # а этот атрибут может присутствовать или отсутствовать

point_2d = Point(False)
print(point_2d.__dict__)  # {'x': 0, 'y': 0}
point_3d = Point(True)
print(point_3d.__dict__)  # {'x': 0, 'y': 0, 'z': 0}

Пример создания атрибута "на ходу":
class Point:
    def __init__(self):
        self.x = 0
        self.y = 0

point = Point()
print(point.__dict__)  # {'x': 0, 'y': 0}
point.name = 'Start'  #  создаём атрибут "на ходу"
print(point.__dict__)  # {'x': 0, 'y': 0, 'name': 'Start'}


Опять же, это не самая хорошая практика - куда лучше, когда набор атрибутов у объекта всегда один и тот же, и не меняется во время выполнения программы. Так меньше путаницы.
Но это пример того, что атрибуты - это, по сути, ключи в связанном с объектом словаре, а потому могут создаваться и изменяться, если это нам требуется.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы