繁体   English   中英

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

[英]Dynamically setting attribute as function in Python class

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

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

我想要达到的目标:

in [0] Player1 = Player()

in [1] Player2 = Player()

in [2]:Player1.SetStrategy('Strategy1')

in [3]:Player2.SetStrategy('Strategy3')

in [4]:Player1.Decision(2,5)

出[0]:10

in [5]:Player2.Decision(3,6)

出[1]:0

在这里和通过google搜索可以为我展示猴子修补的方法,但是这种方法看起来有些不雅(尽管我是初学者,我认为有更好的方法可以做到)-有没有办法通过继承做到这一点?我没看到吗?

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类的方法。 始终保持代码尽可能简单; 当一个函数足够时不要使用类 ; 当类提供某些功能(例如继承)时,请使用该类,这会使基于类的解决方案更加简单。

  3. 在Python中, 不需要setStrategy这样的getter / setter setStrategy 您可以将简单属性用于简单值,将属性用于实现更复杂的行为。 属性和属性使用相同的语法,因此您可以从一个切换到另一个,而不必更改是否使用了类。

  4. 有一个约定(在PEP8中建议),即在CamelCase中命名类,而实例,函数和变量以小写形式命名。 该约定无处不在,遵循该约定将有助于其他人更轻松地理解您的代码。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM