从类中访问类属性

时间:2018-11-25 03:35:04

标签: python oop

我正在为游戏制作幻想编程语言,所以我正在用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 :(得分:1)

我的简单答案是简单地传入解释器本身,然后让对象更改解释器上的相关属性。如果不想过多破坏已有的格式,可以为from csv import writer # open both input and output csv with open("addresses.csv") as csv_in, open("output.csv", "w", newline="") as csv_out: csv_writer = writer(csv_out) # Skip 'Address' header next(csv_in) # Write new headers csv_writer.writerow(["First Address", "Last Address"]) # Go through each line in csv for line in csv_in: # Split ranges from rest of line ranges, *rest = line.split() # Split ranges themselves start, end = ranges.split("-") # Get difference between length of numbers diff = len(start) - len(end) # Create new end address end = start[:diff] + end # Write new lines to output csv csv_writer.writerow([" ".join([start, *rest]), " ".join([end, *rest])]) 函数提供两个参数:

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 ... ,甚至不必关心它是哪种命令。