2013-10-23 111 views
1

我看到了页面:枚举函数?

我很熟悉this SO question在Python中创建枚举。但是,我无法在具有函数的枚举的任何地方找到示例。

我主要是一个Java程序员。 我写了这个代码在Java中:

public enum Role { 
    SOLDIER(4), 
    DEMOMAN(2), 
    SCOUT(4), 
    MEDIC(2); 

    private final int maxPlayers; 

    private Role(int maxPlayers) { 
     this.maxPlayers = maxPlayers; 
    } 

    public int getMaxPlayers() { return maxPlayers; } 
} 

我试图做同样在Python:

class Klass: 
    SCOUT = 1 
    SOLDIER = 2 
    DEMOMAN = 3 
    MEDIC = 4 

    @staticmethod 
    def maxPlayers(klass): 
     return { 
      Klass.SCOUT : 4, 
      Klass.SOLDIER : 4, 
      Klass.DEMOMAN : 2, 
      Klass.MEDIC : 2, 
     }[klass] 

出于某种原因。我觉得我做错了。 将函数关联到Python的枚举的最佳实践是什么?

我实际上并不关心建议的答案是否不使用枚举;我只是想了解在Python中实现上述Java代码的最佳实践。

我愿意在以下使用此枚举:

class Players(dict): 
    def countKlass(self, klass): 
     count = len(filter(lambda x: x == klass, self.values())) 
     return count 
+0

Java代码不是纯枚举;它是枚举的一个子类。如果您只是将Klass更改为Enum的子类(链接中提到的PEP 435枚举),它应该按照您的预期正常工作。它们是整数,所以查词典看起来很简单。 –

+0

这可能有所帮助:http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python – Hoopdady

+0

我的Python代码的作品。但我想这不是最好的做法。 – Nirock

回答

3

让我们记住什么enum S IN的Java真的是 - static final一类的实例。他们真的只是命名常量。

一般来说,Python支持比Java更宽松(或者更喜欢,更灵活)的编码风格。其中一部分就是没有常数,而其中的一部分就是信任你的代码的用户不做疯狂的事情。本着这种精神,你可以这样做,得到你的java代码类似的效果:

class Role(object): 
    class RoleType(object): 
     def __init__(self, maxPlayers): 
      self.maxPlayers = maxPlayers 

    SOLDIER = RoleType(4) 
    DEMOMAN = RoleType(2) 
    SCOUT = RoleType(4) 
    MEDIC = RoleType(2) 

然后你就可以访问它们这样

s = Role.SOLDIER 
print s.maxPlayers # Prints 4 

能做什么不能做是防止用户你的图书馆从创建新的角色。然而,这样做有点尴尬,这应该暗示用户“他们做错了”。

newRole = Role.RoleType(22) # as an example 

如果你走这条路线,你或多或少必须忍受这一点。如果你喜欢使用约定,这通常不会成为问题。他们总是可以访问您定义的值。

2

如果你正在寻找最好的做法,通常你只是做一本字典。

klass = {'SCOUT':4, 
     'SOLDIER':4, 
     'DEMOMAN':2, 
     'MEDIC':2,} 

print klass['MEDIC'] 
2 

如果你想这是一个类的方法,你可以说:

class Klass: 
    def maxPlayers(self, klass): 
     return {'SCOUT':4, 
       'SOLDIER':4, 
       'DEMOMAN':2, 
       'MEDIC':2,}[klass] 

这是你如何使用它:

print Klass().maxPlayers('MEDIC') 
2 
+0

我喜欢这个回答。但它仍然让我做类似'Klass()。maxPlayers('MEDIC')'我认为这不是一个好习惯。因为我必须写'MEDIC'' – Nirock

+0

你是否反对?你想要做什么? – Hoopdady

+0

我认为这里的问题是,这使得它不太清楚'maxPlayers'实际上是'MEDIC'的一个事实上的属性,这是OP想要这样做的方式。 –

1

使用AutoEnum recipe,你的代码看起来是这样的:

class Role(AutoEnum): 

    SCOUT = 4 
    SOLDIER = 4 
    DEMOMAN = 2 
    MEDIC = 2 

    def __init__(self, max_players): 
     self.max_players = max_players 

现在你有了新的Python枚举的好处(backported if you don't have 3.4):

--> Role.SCOUT 
<Role.SCOUT: 3> 
--> Role.SCOUT.max_players 
4