Python 如何使用策略模式访问字段?

How to access fields with StrategyPattern in Python?

我正在尝试使用策略模式为不同规模的模拟包含不同的行为。

我遇到了 this implementation from the first example of the book Head First Design Patterns

但是,我不知道我应该在哪里以及如何访问我在模拟中初始化的数据。

from abc import ABCMeta, abstractmethod
###########################################################################    #####
# Abstract Simulation class and concrete Simulation type classes.
################################################################################

class Simulation:
    def __init__(self, run, plot):
        self._run_behavior = run
        self._plot_behavior = plot

    def run(self):
        return self._run_behavior.run()

    def plot(self):
        return self._plot_behavior.plot()        

class SmallSimulation(Simulation):
    def __init__(self):
        Simulation.__init__(self, Run(), Plot())
        print "I'm a small simulation"
        self.data = 'Small Data'

class BigSimulation(Simulation):
    def __init__(self):
        Simulation.__init__(self, Run(), Plot())
        print "I'm a big simulation"
        self.data = 'Big Data'

class LargeSimulation(Simulation):
    def __init__(self):
        Simulation.__init__(self, RunLarge(), Plot())
        print "I'm a large simulation"
        self.data = 'Large Data'

################################################################################
# Run behavior interface and behavior implementation classes.
################################################################################

class RunBehavior:
    __metaclass__ = ABCMeta
    @abstractmethod 
    def run(self):
        pass

class Run(RunBehavior):
    def run(self):
        print "I'm running standard"
        print self.data

class RunLarge(RunBehavior):
    def run(self):
        print "I'm running multilevel"


################################################################################
# Plot behavior interface and behavior implementation classes.
################################################################################

class PlotBehavior:
    __metaclass__ = ABCMeta
    @abstractmethod 
    def plot(self):
        pass

class Plot(PlotBehavior):
    def plot(self):
        print "I'm plotting results"

################################################################################
# Test Code.
################################################################################

if __name__ == '__main__':
    smallSimulation = SmallSimulation()
    bigSimulation = BigSimulation()
    largeSimulation = LargeSimulation()

    print('='*20)
    print('Execution')
    smallSimulation.run()
    bigSimulation.run()
    largeSimulation.run()

    print('='*20)
    print('Plotting')
    smallSimulation.plot()
    bigSimulation.plot()
    largeSimulation.plot()

输出是

I'm a small simulation
I'm a big simulation
I'm a large simulation
====================
Execution
I'm running standard
Traceback (most recent call last):
  File "strategy.py", line 84, in <module>
    smallSimulation.run()
  File "strategy.py", line 16, in run
    return self._run_behavior.run()
  File "strategy.py", line 52, in run
    print self.data
AttributeError: 'Run' object has no attribute 'data'

我应该如何初始化和访问我的数据?

您的 运行 class 没有数据属性,因此出现异常。

class Run(RunBehavior):
# This class does NOT have a data attribute
    def run(self):
        print "I'm running standard"
        print self.data

要在 Run 中访问模拟的 data,您可以将其传递到 运行 的 init():

class Run(RunBehavior):
    def __init__(self, data):
       self.data = data
    def run(self):
       print "I'm running standard"
       print self.data