在Python类中将属性动态设置为函数

时间:2014-04-20 12:13:03

标签: python python-2.7

我正在创建一个简单的游戏,其中包含名为' Player'和'策略'。我想在创建播放器时将一个策略实例分配给播放器实例。

class Player(object):

    def __init__(self):
        self.Strategy = None

    def Decision(self, InputA, InputB):

        Result = self.Strategy(InputA, InputB)
        return Result

    def SetStrategy(self):
        # Sets a strategy instance to the Player instance


class Strategy(object):

    def Strategy1(self, InputA, InputB):
        return InputA * InputB

    def Strategy2(self, InputA, InputB):
        return (InputA - InputB) / 2

    def Strategy3(self, InputA, InputB):
        return 0

我想要实现的目标:

在[0] Player1 = Player()

在[1] Player2 = Player()

中 [2]中的

:Player1.SetStrategy(' Strategy1')

中的

:Player2.SetStrategy(' Strategy3')

[4]中的

:Player1.Decision(2,5)

out [0]:10

中的

:Player2.Decision(3,6)

out [1]:0

在这里搜索并通过谷歌向我展示了使用猴子修补的方法,但这种方法看起来有点不雅(虽然我是初学者,但我认为这是更好的方法) - 是否有用我没有看到的继承做到这一点的方法?

1 个答案:

答案 0 :(得分:1)

def strategy1(inputA, inputB):                  # 2
    return inputA * inputB

def strategy2(inputA, inputB):
    return (inputA - inputB) / 2

def strategy3(inputA, inputB):
    return 0

strategy = {
    'mul': strategy1,
    'diff': strategy2,
    'zero': strategy3
}

class Player(object):

    def __init__(self, strategy_name='mul'):      # 1
        self.strategy_name = strategy_name        # 5

    def decision(self, inputA, inputB):           # 4
        result = strategy[self.strategy_name](inputA, inputB)
        return result

player1 = Player()
player2 = Player()
player1.strategy_name = 'mul'                     # 3
player2.strategy_name = 'zero'
print(player1.decision(2, 5))
# 10

print(player2.decision(3, 6))
# 0

  1. 每个玩家都有策略,所以不要允许玩家实例化 没有分配一些策略。您可以使用默认策略 (如下所示),或使strategy成为强制性参数。

  2. 策略可以是简单的功能;我没有理由 将它们捆绑为Strategy类的方法。始终保持代码为 尽可能简单; don't use a class when a function would suffice; 当它提供一些特性(如继承)时使用一个类 使基于类的解决方案更简单。

  3. 在Python中,no need for getters/setterssetStrategy类似。 您可以将简单值和属性的普通属性用于 实现更复杂的行为。属性和属性使用 相同的语法,所以你可以从一个切换到另一个没有 必须改变才能使用该类。

  4. 有一个约定(在PEP8中推荐)可以命名类 CamelCase,以及小写的实例,函数和变量。该 惯例被无处不在地使用,并且遵循它将有助于其他 更容易理解您的代码。

  5. 为了便于将策略存储在数据库中,您可以存储 数据库中的strategy_name,并使用查找字典(例如 strategy)将名称与实际功能相关联。