Привет всем!
Вот в чем дело. Итак, я сначала хотел создать класс Робота, я хочу, чтобы он передвигался по какой-нибудь доске. Может быть, 10×10 или что-то в этом роде, тогда я хотел изобрести класс боевых роботов, я хочу добавить классных игроков (потому что я хочу играть между игроком 1 и игроком 2), но вот это то, что у меня так много.
Давайте сосредоточимся на этом коде, потому что я хочу, чтобы он улучшил его, а затем приступил к созданию боев роботов!
class Robot:
def __init__(self, name, place, start = (0,0), power = 9):
self.name = name
self.start = start
self.place = place
self.power = power
def get_name(self):
return self.name
def get_start(self):
return self.start
def get_place(self):
return self.place
def get_power(self):
return self.power
def set_name(self, x):
if isinstance(x, str):
self.name = x
else:
raise TypeError("must be a string")
def set_start(self, x):
if isinstance(x, tuple):
self.start = x
else:
raise TypeError("must be a tuple")
def set_place(self, x):
if isinstance(x, list):
self.place = x
else:
raise TypeError("must be a list")
def set_power(self, x):
if isinstance(x, int):
self.power = x
else:
raise TypeError("must a int")
def check_power(self):
if self.power <= 0:
raise ValueError("No power")
def left(self, value):
self.check_power()
self.power -= value
if self.place[0] - value < 0:
self.place[0] = self.place[0] - value + 8
else:
self.place[0] = self.place[0] - value
def up(self, value):
self.check_power()
self.power -= value
if self.place[1] + value > 7:
self.place[1] = self.place[1] + value - 8
else:
self.place[1] = self.place[1] + value
if self.place[1] == 5:
self.power += 2
def __str__(self):
return self.name, self.place, self.power
Также хочу, чтобы я стал лучше в этом. Что ж, сила будет важна в боях роботов, потому что если какой-то робот от игрока 1 будет рядом с роботом от игрока 2, я хочу, чтобы вы знали, сражайтесь, так что сила будет довольно хорошей прямо здесь, если они будут рядом с друг друга мощность будет уменьшаться, пока робот не будет уничтожен. Но давайте сосредоточимся на приведенном выше коде, чтобы сделать его лучше.
Любые советы, как сделать это короче и аккуратнее, ближе к продвинутому или просто лучшему решению, будут определенно к делу.
Хорошего дня!
1 ответ
Аннотации типов
Использование аннотаций типов сделает вашу программу более читаемой и простой в отладке. Например:
def __init__(self, name, place, start = (0,0), power = 9):
# assignments
становится
def __init__(self, name: str, place : List[int], start: Tuple[int, int] = (0,0), power: int = 9):
# assignments
Я импортировал List, Tuple от typing модуль из стандартной библиотеки:
from typing import List, Tuple
Вот дополнительная информация об использовании аннотаций типов.
Получатель и сеттер
Использование геттеров и сеттеров довольно непифонично. Вместо этого вы можете изменить поведение получения и настройки с помощью @property декоратор вроде этого:
def __init__(self, name: str, place : List[int], start: Tuple[int, int] = (0,0), power: int = 9):
self._name = name
# further assignments
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if isinstance(value, str):
self._name = value
else:
raise TypeError("must be a string")
Это позволит вам использовать свойства без явного вызова методов получения и установки:
my_robot.name="foo"
print(my_robot.name)
Этот вопрос о StackOverflow содержит более подробные пояснения.
Логика
- Вам также следует взглянуть на свои сеттеры для
placeа такжеstart. Вы проверяете только тип переданного аргументаvalue, но не проверяйте, находятся ли элементы вlistили жеtupleотносятся к типуint. - Вы можете рассмотреть возможность использования настраиваемого класса
Positionили аналогичный для обработки позиционной логики робота. Таким образом, вы можете получить доступ к различным измерениям по их именам, а не по индексамplace(self.place[0]или жеself.place[1]). Вы также сможете добавить в него дополнительную логику (например, отсечение и т. Д.). powerа такжеcheck_power(): В зависимости от предполагаемой функциональности вы можете ограничить количество шагов, которые может сделать робот, доpowerчто он ушел. В настоящее время робот может делать любое количество шагов, пока онpower > 0оставил.- Вы должны проверить работоспособность
left(value)а такжеup(value)для больших значений, особенно для значений, которые> 2 * board_dimension. Я подозреваю, что результаты могут быть непреднамеренными.

В целом согласен. Я бы пошел дальше ваших «непифонических функций доступа» — если есть какая-то нетривиальная логика для получения или установки,
@propertyтребуется, но здесь его нет. Просто сделайте «общедоступную» переменную.— Райндериен
Подлинный вопрос: как вы затем проверяете / гарантируете, что присвоены только значения определенного типа общественный атрибуты, если вообще?
— рискованный пингвин
Короткий ответ — нет. Проверка типа — как правило — не выполняется вообще, поскольку Python использует утиную типизацию. Недавняя поддержка статического анализа типов полезна, но не применяется во время выполнения. Если вы действительно хотите применить проверку к значению перед установкой, вы должны сделать это, как показано, с помощью
@propertiesили — если вы можете сделать класс неизменяемым, что имеет много преимуществ — тогда во время__init__.— Райндериен