Передача списка из функции в класс в Python

Я хочу вывести функцию 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)

Да, вам просто нужно переместить метод в функцию, используя правила рефакторинга. Я сделаю это в PyCharm, чтобы увидеть.

quamrana 09.12.2020 21:30
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я думаю, есть много способов, и, кстати, ваш исходный код тоже действителен. Если вы настаиваете на том, чтобы вынести 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")

Спасибо! Также очень приятно коснуться вашего последнего комментария, только что реализовал это тоже

Becky8 09.12.2020 21:47
Ответ принят как подходящий

Это можно сделать так. Как показывают другие ответы, существует множество комбинаций.

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))
            )

Большое спасибо!

Becky8 09.12.2020 21:47

Другие вопросы по теме