Доступ к свойствам класса из класса - PullRequest
0 голосов
/ 25 ноября 2018

Я создаю фэнтезийный язык программирования для игры, и поэтому я пишу язык и интерпретатор на python.Язык работает как поток команд, каждая из которых интерпретируется каждым «шагом».Вводится строка кода и преобразуется в список объектов команд.Интерпретатор обрабатывает команды, но некоторые команды должны иметь возможность доступа к атрибутам интерпретатора.

Например, интерпретатор отслеживает активную команду (пронумерованную от первой команды), поэтому команда gotoпотребуется изменить активную команду.В настоящее время я делаю это, передавая данные в команду, она модифицируется, и интерпретатор устанавливает свой атрибут равным ему.

self.current = active.evaluate(self.current)

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

        if active.complete():  # on command completion
            type = active.return_type  # get return type
            # passes in requested data to modify
            if type == "var":  # changing var stream
                self.var = active.evaluate(self.var)
            elif type == "stream":  # changing packet stream
                self.stream = active.evaluate(self.stream)
            elif type == "current":  # changing current packet
                self.current = active.evaluate(self.current)
            elif type == "value":  # returns argument for next command
                self.holder = active.evaluate(self.var)
                self.resolve = True
            elif type == "none":
                active.evaluate()

Это кажется неудобным способом ведения дел, есть ли лучший способ изменения атрибутов класса изнутри класса?

1 Ответ

0 голосов
/ 25 ноября 2018

Мой простой ответ - просто передать сам интерпретатор и позволить объекту изменить соответствующее свойство интерпретатора.Если вы не хотите слишком сильно отделяться от формата, который у вас уже есть, вы могли бы дать функции evaluate() два аргумента:

def evaluate(interpreter, field_name):
    interpreter.setattr(field_name, some_value)

, которые вы затем назвали бы как

active.evaluate(self, "var")

Однако это кажется хорошим местом для реализации полиморфизма, который решит как проблему, о которой вы спрашиваете, так и устранит необходимость в растущем стеке if операторов.

Во-первых,допустим, у вас есть суперкласс для команд:

class Command:
    def complete():
        # do something, return a boolean

    def evaluate(interpreter):
        raise NotImplementedException()

В настоящее время кажется, что вы используете команду return_type, чтобы изменить то, что вы делаете с командой.Но почему бы просто не определить, какой тип команды будет выполняться, и создать экземпляр другого подкласса с другим поведением соответственно?

class GotoCommand(Command):
    def evaluate(interpreter):
        interpreter.current = some_value

class PacketCommand(Command):
    def evaluate(interpreter):
        interpreter.stream = some_other_value

...

, после чего вы можете просто вызвать active.evaluate(self) в интерпретаторе, даже не имеявсе равно, что это за команда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...