Мне нужна помощь, чтобы разобраться в мелочах, написанных на python, и какие улучшения можно сделать в приведенном ниже коде. например
- Должны ли мы сделать атрибуты класса закрытыми / защищенными?
- Не могу понять роль @property
- Стоит ли читать вопросы из файла?
- Есть ли другие предложения, которые вы хотели бы дать?
Здесь вы можете найти код —
class Game:
def __init__(self):
self.players = []
self.places = [0] * 6
self.purses = [0] * 6
self.in_penalty_box = [0] * 6
self.pop_questions = []
self.science_questions = []
self.sports_questions = []
self.rock_questions = []
self.current_player = 0
self.is_getting_out_of_penalty_box = False
for i in range(50):
self.pop_questions.append("Pop Question %s" % i)
self.science_questions.append("Science Question %s" % i)
self.sports_questions.append("Sports Question %s" % i)
self.rock_questions.append(self.create_rock_question(i))
def create_rock_question(self, index):
return "Rock Question %s" % index
def is_playable(self):
return self.how_many_players >= 2
def add(self, player_name):
self.players.append(player_name)
self.places[self.how_many_players] = 0
self.purses[self.how_many_players] = 0
self.in_penalty_box[self.how_many_players] = False
print(player_name + " was added")
print("They are player number %s" % len(self.players))
return True
@property
def how_many_players(self):
return len(self.players)
def roll(self, roll):
print("%s is the current player" % self.players[self.current_player])
print("They have rolled a %s" % roll)
if self.in_penalty_box[self.current_player]:
if roll % 2 != 0:
self.is_getting_out_of_penalty_box = True
print("%s is getting out of the penalty box" % self.players[self.current_player])
self.places[self.current_player] = self.places[self.current_player] + roll
if self.places[self.current_player] > 11:
self.places[self.current_player] = self.places[self.current_player] - 12
print(self.players[self.current_player] +
''s new location is ' +
str(self.places[self.current_player]))
print("The category is %s" % self._current_category)
self._ask_question()
else:
print("%s is not getting out of the penalty box" % self.players[self.current_player])
self.is_getting_out_of_penalty_box = False
else:
self.places[self.current_player] = self.places[self.current_player] + roll
if self.places[self.current_player] > 11:
self.places[self.current_player] = self.places[self.current_player] - 12
print(self.players[self.current_player] +
''s new location is ' +
str(self.places[self.current_player]))
print("The category is %s" % self._current_category)
self._ask_question()
def _ask_question(self):
if self._current_category == 'Pop': print(self.pop_questions.pop(0))
if self._current_category == 'Science': print(self.science_questions.pop(0))
if self._current_category == 'Sports': print(self.sports_questions.pop(0))
if self._current_category == 'Rock': print(self.rock_questions.pop(0))
@property
def _current_category(self):
if self.places[self.current_player] == 0: return 'Pop'
if self.places[self.current_player] == 4: return 'Pop'
if self.places[self.current_player] == 8: return 'Pop'
if self.places[self.current_player] == 1: return 'Science'
if self.places[self.current_player] == 5: return 'Science'
if self.places[self.current_player] == 9: return 'Science'
if self.places[self.current_player] == 2: return 'Sports'
if self.places[self.current_player] == 6: return 'Sports'
if self.places[self.current_player] == 10: return 'Sports'
return 'Rock'
def was_correctly_answered(self):
if self.in_penalty_box[self.current_player]:
if self.is_getting_out_of_penalty_box:
print('Answer was correct!!!!')
self.purses[self.current_player] += 1
print(self.players[self.current_player] +
' now has ' +
str(self.purses[self.current_player]) +
' Gold Coins.')
winner = self._did_player_win()
self.current_player += 1
if self.current_player == len(self.players): self.current_player = 0
return winner
else:
self.current_player += 1
if self.current_player == len(self.players): self.current_player = 0
return True
else:
print("Answer was corrent!!!!")
self.purses[self.current_player] += 1
print(self.players[self.current_player] +
' now has ' +
str(self.purses[self.current_player]) +
' Gold Coins.')
winner = self._did_player_win()
self.current_player += 1
if self.current_player == len(self.players): self.current_player = 0
return winner
def wrong_answer(self):
print('Question was incorrectly answered')
print(self.players[self.current_player] + " was sent to the penalty box")
self.in_penalty_box[self.current_player] = True
self.current_player += 1
if self.current_player == len(self.players): self.current_player = 0
return True
def _did_player_win(self):
return not (self.purses[self.current_player] == 6)
from random import randrange
if __name__ == '__main__':
not_a_winner = False
game = Game()
game.add('Chet')
game.add('Pat')
game.add('Sue')
while True:
game.roll(randrange(5) + 1)
if randrange(9) == 7:
not_a_winner = game.wrong_answer()
else:
not_a_winner = game.was_correctly_answered()
if not not_a_winner: break
1 ответ
- Конечно, всякий раз, когда вы видите, что данный метод предназначен только для внутреннего использования, вы должны сделать его закрытым. Это позволяет скрыть детали вашей реализации, особенно те, которые могут быть изменены в будущем, и вы хотите быть уверены, что никто не будет использовать это вне класса. Это также помогает при чтении кода класса, поскольку говорит, что является «точкой входа» в класс.
- свойство просто помогает контролировать способ ввода и вывода некоторого внутреннего значения. Иногда вы можете захотеть проверить его или произвести дополнительные вычисления и т. Д., Чтобы вы могли сделать это со свойствами и так называемыми геттерами и сеттерами.
- Вопрос, следует ли вам читать что-либо из файла, сильно зависит от ваших потребностей и возможностей — сколько вопросов вы ожидаете получить? Будут ли они изменены в будущем? Что делать, если такого файла нет?
- Я могу взглянуть на этот код несколько позже, но на этом этапе я бы начал с избегания магических чисел (например,
6
,11
и т. д.) и поместите их либо в константу, либо в перечисление. Также, пожалуйста, взгляните на PEP8 где вы можете найти несколько советов по укладке.
Некоторые дополнительные примечания:
- какую версию Python вы используете? Я надеюсь, что вы учитесь с недавним, поэтому, пожалуйста, измените % -строки к ф-струны так
"Pop Question %s" % i
может быть простоf"Pop Question {i}"
. - также хорошо использовать подсказки типа. Трудно догадаться, чего следует ожидать от определения
roll(self, roll)
. Чтоroll
? Что должен вернуть и т. Д. Простоmake_roll(self, roll: int) -> None: ...
говорит, что эта функцияmake_roll
использует целочисленный параметр и ничего не возвращает. - как было сказано ранее, используйте константы вместо простых чисел, так как трудно сказать, что на самом деле здесь происходит
if randrange(9) == 7:
Добро пожаловать в Code Review! Обратите внимание, что вопросы, связанные с кодом, в которых OP запрашивает объяснение, не относятся к теме на этом сайте. Если OP редактирует свое сообщение, чтобы решить проблему и сделать свое сообщение по теме, они могут сделать ваш ответ спорным. На такие вопросы рекомендуется не отвечать.. Совет: нужно ответить на множество вопросов по теме; вы быстрее заработаете себе репутацию, если проанализируете код в вопросах, которые получат большее количество просмотров из-за того, что они соответствуют теме.
— БУДЕТ ONᴇᴌᴀ
@ SᴀᴍOnᴇᴌᴀ Теперь я это вижу. Спасибо!
— Адам Токарски