Почему это работает в Python? Создание экземпляра, установка несуществующего атрибута в этом классе, затем печать этого атрибута через экземпляр - PullRequest
0 голосов
/ 14 марта 2020

Я смотрел на YouTube урок о python классах.

Это код, который он написал.

class Tweet :
  pass

a = Tweet()

a.message = '140 chars'

print (a.message)

# This works

print(Tweet.message)

# This doesn't

Я понимаю, почему печать tweet.message не работает (или, по крайней мере, я думаю, что это так, если это так просто и просто, как кажется), но почему печать a.message работает? Я предполагаю, что это как-то связано с тем, как работает python, но что это?

На самом деле, теперь, когда я думаю об этом, может быть, я ошибаюсь. Я думал, что Tweet.Message не печатает, потому что у твита есть сообщение, которое вы можете установить. Но python автоматически создает способность делать a.message? Таким образом, причина, по которой tweet.message не печатает его, потому что это всего лишь план, вы можете извлекать данные только из экземпляров, а не из самого класса?

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Python позволяет динамически добавлять новые атрибуты к объекту, даже если он не "объявлен" в сигнатуре класса или не назначен во время инициализации объекта в методе __init__.

При выполнении назначения a.message = "...", атрибут message добавляется только к объекту a, но не к классу Tweet или к любым другим объектам того же типа. Если у вас есть другой объект b типа Tweet и вы пытаетесь получить доступ к его атрибуту message напрямую, вы получите AttributeError.

Вот подробный пример:

class Tweet:
  def __init__(self):
    self.user = "default_user"

a = Tweet()
print(a.user)     # "default_user"
a.message = "140 chars"
print(a.message)  # "140 chars"

b = Tweet()
print(b.user)     # "default_user"
print(b.message)  # AttributeError: 'Tweet' object has no attribute 'message'

print(Tweet.user)     # AttributeError: type object 'Tweet' has no attribute 'user'
print(Tweet.message)  # AttributeError: type object 'Tweet' has no attribute 'message'
0 голосов
/ 14 марта 2020

Tweet.message ищет атрибут с именем message в классе Tweet, который не существует.

a.message ищет атрибут с именем message в * экземпляре Tweet, который существует. (Если этого не произойдет, он обратится к поиску атрибута типа a.)

a.message = "140 chars" всегда устанавливает значение атрибута (создавая его, при необходимости) на объекте a. Он никогда не изменит значение атрибута class , если он существует. Например,

class Tweet:
    length = 140

t = Tweet()
t.length = 19

assert Tweet.length == 140
assert t.length == 19

Язык Python не позволяет объявить, какие атрибуты будет иметь экземпляр класса. Все атрибуты экземпляра создаются с помощью присваиваний, подобных t.length = 19. Обычно вы создаете атрибуты внутри определения __init__, так что все они создаются в одном месте и сразу после создания экземпляра. Таким образом, вместо

class Tweet:
    pass

t = Tweet()
t.message = "140 chars"

вы пишете

class Tweet:
    def __init__(self):
        self.message = "140 chars"

t = Tweet()

Нет реальной разницы между заданиями t.message = "140 chars" и self.message = "140 chars", за исключением случаев, когда они точно выполняются и имя, используемое для обозначения объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...