简体   繁体   English

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

[英]Dynamically setting attribute as function in Python class

I am creating a simple game that contains classes called 'Player' and 'Strategy'. 我正在创建一个简单的游戏,其中包含名为“ Player”和“ Strategy”的类。 I want to assign a Strategy instance to the Player instance when the Player is created. 创建播放器时,我想将策略实例分配给播放器实例。

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

What I'm trying to achieve: 我想要达到的目标:

in[0] Player1 = Player() in [0] Player1 = Player()

in[1] Player2 = Player() in [1] Player2 = Player()

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

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

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

out[0]: 10 出[0]:10

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

out[1]: 0 出[1]:0

Searching here and via google shows me ways of doing it with monkey patching but the approach looks a little inelegant (and although I'm a beginner I think there's a better way to do it) - is there a way to do this with inheritance that I'm not seeing? 在这里和通过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. Every player has a strategy, so don't allow instantiation of Player without assigning some strategy. 每个玩家都有一个策略,因此在没有分配某些策略的情况下不允许实例化玩家。 You could use a default strategy (as shown below), or make strategy a mandatory argument. 你可以使用默认的策略(如下图所示),或进行strategy强制性的说法。

  2. The strategies could be plain functions; 这些策略可以是简单的功能; I don't see a reason to bundle them as methods of a Strategy class. 我认为没有理由将它们捆绑为Strategy类的方法。 Always keep code as simple as possible; 始终保持代码尽可能简单; don't use a class when a function would suffice ; 当一个函数足够时不要使用类 ; use a class when it provides some feature (such as inheritance) which makes the class-based solution simpler. 当类提供某些功能(例如继承)时,请使用该类,这会使基于类的解决方案更加简单。

  3. In Python there is no need for getters/setters like setStrategy . 在Python中, 不需要setStrategy这样的getter / setter setStrategy You can use plain attributes for simple values, and properties to implement more complicated behavior. 您可以将简单属性用于简单值,将属性用于实现更复杂的行为。 Attributes and properties use the same syntax, so you can switch from one to the other without having to change have the class is used. 属性和属性使用相同的语法,因此您可以从一个切换到另一个,而不必更改是否使用了类。

  4. There is a convention (recommended in PEP8) that classes be named in CamelCase, and instances, functions and variables in lowercase. 有一个约定(在PEP8中建议),即在CamelCase中命名类,而实例,函数和变量以小写形式命名。 The convention is used ubiquitously, and following it will help other understand your code more easily. 该约定无处不在,遵循该约定将有助于其他人更轻松地理解您的代码。

  5. To make it easy to store the strategy in a database, you could store the strategy_name in the database, and use a lookup dict (such as strategy ) to associate the name with the actual function. 为了便于将策略存储在数据库中,可以将strategy_name存储在数据库中,然后使用查找字典(例如strategy )将名称与实际函数相关联。

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

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