Я хочу вывести функцию load_words
из класса Game
(поскольку она действительно не зависит от класса — скорее наоборот). И все же иметь возможность ссылаться и использовать список, который я создаю в load_words
в классе. Как мне это сделать?
class Game:
def __init__(self, words_file, matrix_size):
self._words_file = words_file
self._matrix_size = matrix_size
self._attempt_count = 0
if matrix_size % 2 != 0:
raise Exception("Invalid matrix size, has to be an even number, size now =%d" % matrix_size)
self.load_words()
if len(self._words) < matrix_size * matrix_size // 2:
raise Exception(
"Words list is too small for matrix of %d cells, words=%d"
% (matrix_size, len(self._words))
)
def load_words(self):
self._words = set()
with open(self._words_file) as f:
for line in f.readlines():
line = line.strip()
if line != "":
self._words.add(line)
Я думаю, есть много способов, и, кстати, ваш исходный код тоже действителен. Если вы настаиваете на том, чтобы вынести load_words
за пределы класса, то сработает что-то вроде этого:
class Game:
def __init__(self, words_file, matrix_size):
# your code
def load_words_to_class(self, words):
self._words = words
# rest of the code to check what you want with self._words
def load_words(self):
# your code to load words
game = Game()
game.load_words_to_class(words)
Вы должны предоставить слова Game.__init__
в качестве аргумента. Независимо от того, происходит ли этот список из жестко закодированного списка или считывается из файла, это не имеет значения. Для получения слов из файла можно использовать отдельный метод класса.
class Game:
def __init__(self, words, matrix_size):
self._words_file = words_file
self._matrix_size = matrix_size
self._attempt_count = 0
if matrix_size % 2 != 0:
raise Exception("Invalid matrix size, has to be an even number, size now =%d" % matrix_size)
if len(self._words) < matrix_size * matrix_size // 2:
raise Exception(
"Words list is too small for matrix of %d cells, words=%d"
% (matrix_size, len(self._words))
)
@classmethod
def from_file(cls, word_file, matrix_size):
words = {}
with open(words_file) as f:
for line in f:
line = line.strip()
if line != "":
words.add(line)
return cls(words, matrix_size)
g = Game.from_file("words.txt", 20)
В качестве дополнительной функции вместо того, чтобы заставлять вызывающую сторону вычислять размер, рассмотрите возможность вычисления размера матрицы из любого предоставленного списка слов.
class Game:
def __init__(self, words):
self._words_file = words_file
self._matrix_size = matrix_size
self._attempt_count = 0
self.matrix_size = math.sqrt(len(self._words)*2) # roughly
@classmethod
def from_file(cls, word_file):
words = {}
with open(words_file) as f:
for line in f:
line = line.strip()
if line != "":
words.add(line)
return cls(words)
g = Game.from_file("words.txt")
Чтобы еще больше упростить дизайн, вы можете признать, что чтение слов из файла на самом деле не относится к классу Game
, но в то же время конкретный формат файла может сделать такую функцию обычно непригодной для использования вне класса, путем определения частного статического метод.
class Game:
def __init__(self, words):
self._words_file = words_file
self._matrix_size = matrix_size
self._attempt_count = 0
self.matrix_size = math.sqrt(len(self._words)*2) # roughly
@staticmethod
def _read_words_from_file(word_file):
with open(words_file) as f:
for line in f:
line = line.strip()
if line != "":
yield line
@classmethod
def from_file(cls, word_file):
words = set(cls._read_words_from_file(word_file))
return cls(words)
g = Game.from_file("words.txt")
Спасибо! Также очень приятно коснуться вашего последнего комментария, только что реализовал это тоже
Это можно сделать так. Как показывают другие ответы, существует множество комбинаций.
def load_words(file, words):
with open(file) as f:
for line in f.readlines():
line = line.strip()
if line != "":
words.add(line)
class Game:
def __init__(self, words_file, matrix_size):
self._words_file = words_file
self._matrix_size = matrix_size
self._attempt_count = 0
if matrix_size % 2 != 0:
raise Exception("Invalid matrix size, has to be an even number, size now =%d" % matrix_size)
self._words = set()
load_words(self._words_file, self._words)
if len(self._words) < matrix_size * matrix_size // 2:
raise Exception(
"Words list is too small for matrix of %d cells, words=%d"
% (matrix_size, len(self._words))
)
Большое спасибо!
Да, вам просто нужно переместить метод в функцию, используя правила рефакторинга. Я сделаю это в PyCharm, чтобы увидеть.