Как разместить несколько элементов внутри атрибута класса python3
Я работаю над текстовой рекламой. У меня есть класс комнаты и класс предметов, но когда я помещаю в комнату более одного предмета, у меня возникают проблемы. Вот пример кода:
class Place(object):
"""The Room class"""
def __init__(self, name, Item):
self.name = name
self.Item = Item
class Item():
"""The Item class"""
def __init__(self, name):
self.name = name
PC = Item("PC")
Bed = Item("Bed")
bedroom = Place(name = "Bedroom", Item = {PC, Bed})
print (bedroom.Item.name)
И сообщение об ошибке:
Traceback (most recent call last):
File "C:\Documents and Settings\Kenneth\My Documents\Python_Projects\projects\
TA.Project\location\classes2.py", line 18, in <module>
print (bedroom.Item.name)
AttributeError: 'set' object has no attribute 'name'
Press any key to continue . . .
Это работает, когда у меня есть только один элемент, но когда я пытаюсь добавить еще, я получаю ошибки. Я пытался создать цикл для показа одного элемента за раз, но это тоже не сработало. Любая помощь приветствуется. Спасибо.
Цикл, который я пробовал, был чем-то вроде:
for i in bedroom.Item:
print (i)
Attributeerror 'Place' объект не имеет атрибута 'Item'
Ответ принят, я хотел бы обновить код для всех, у кого есть похожая проблема:
class Place:
def __init__(self, name: str, items: set):
self.name = name
if items is None:
items = set()
self.items = items
def get_item_names(self):
# one-liner: return [x.name for x in self.items]
names = []
for item in self.items:
names.append(item.name)
return '\n'.join(names)
def get_item_value(self):
value = []
for item in self.items:
value.append(item.value)
return value
class Item:
def __init__(self, name: str, value: iter):
self.name = name
self.value = value
Bed=Item("Bed", 200)
Chair=Item("Chair", 10)
Oven=Item("Oven", 500)
bedroom = Place("Bedroom", {Bed, Chair})
kitchen = Place("Kitchen", {Oven})
print (bedroom.get_item_names)
Функция values должна была доказать, что класс Item все еще работает.
1 ответ
Не используйте имена классов как имена переменных! Это только сбивает с толку и приводит к ошибкам.:)
Для меня это работает с bedroom.Item
без проблем, но, возможно, вы поменяли местами прописные / строчные буквы?!
AttributeError: 'Place' object has no attribute 'Item'
значит твой Place
-класс не предоставляет переменную Item
, Так что если вы на самом деле назвали переменную item
или же Items
, вам придется просить об этом, а не о Item
,
Уже написано до обновления на вопрос:
Когда вы используете несколько предметов в одной комнате, вы вместо того, чтобы иметь только один конкретный предмет, даете Place
набор предметов. Так что при выполнении bedroom.Item.name
вы на самом деле спрашиваете set
, Хранится в bedroom.Items
чтобы дать вам это name
(чего он не обеспечивает, поэтому ошибка).
Я бы порекомендовал четкое определение. Позволять Place
всегда ожидайте нескольких элементов (возможно, есть только один, но если он все еще в наборе, то мое предложение в любом случае работает).
Пример:
class Place:
def __init__(self, name: str, items: set):
# The `items: set` notation is only for better understanding.
# It is valid Python3 syntax, but does not ensure the actual type!
self.name = name
if items is None:
item = set() # this is to avoid possible erros later.
self.items = item
def get_item_names(self):
# one-liner: return [x.name for x in self.items]
names = []
for item in self.items:
names.append(item.name)
return names
class Item:
def __init__(self, name: str):
self.name = name
bedroom = Place("Bedroom", {Item("Bed"), Item("Chair")})
kitchen = Place("Kitchen", {Item("Oven")})
# usage:
>>> print(bedroom.get_item_names())
["Bed", "Chair"]
>>> print(kitchen.get_item_names())
["Oven"]
Основным отличием является использование цикла (в get_item_names
) чтобы получить все эти имена. Если вы хотите сами следить за предметами, вы все равно получили items
-набор, по которому вы можете повторять:
>>> for item in bedroom.items:
... print(item.name + ":", item)
Bed: <__main__.Item object at 0x7f0c081327f0>
Chair: <__main__.Item obect at 0x7f0c08132898>