2015-05-27 50 views
2

我正在使用python创建一个Dungeons and Dragons Character Creator,并且正在编写这些武器。我重新创建了一些在以前的类似环境中无法工作的代码,并且我想知道如何在不需要每个变量的if语句的情况下工作,以便可以编辑其他属性和项目。在for循环中创建一个变量

目标是创建一个仅具有与其关联的属性(变量)的武器(对象)。

目前代码:

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = [finesse, light, thrown, two_handed, versatile] 
     for prop in property_list: 
      if prop != 0: 
       self.prop = prop 

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 

目前的变量不会为武器来创建;因此

dagger.finesse 

不存在。理想情况下,'finesse'将存储在变量dagger.finesse中,而变量dagger.two_handed不会由代码创建。

我可能忽略了一些简单的问题,并且可能存在重复的问题,但是我找不到与我正在寻找的答案类似的问题。

谢谢所有谁回答

编辑

谢谢@WKPlus一些格式化援助;我是新来的stackoverflow网站

我已经意识到感谢@abarnert更好的方式来做到这一点是要在变量中列出porperties并稍后在属性的代码中检查该变量,如所以

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = [finesse, light, thrown, two_handed, versatile] 
     self.properties = [] 
     for prop in property_list: 
      if prop != 0: 
       self.properties.append(prop) 

但是,我仍然希望看到我原来的问题可能是如何回答的,因为它仍然可以运行像我原来不排除语句非常有用。

+2

你为什么想'Weapon.finesse'是字符串''finesse''或不存在?岂不是更好吗?比如说,对于匕首来说这是真的,对俱乐部来说是虚假的? – abarnert

+0

想想你将如何使用它。你想尝试:除AttributeError之外的player.weapon.finesse:遍及代码吗? – abarnert

+0

理想情况下,会有多个'Weapon'的子类。 – TigerhawkT3

回答

3

这会工作:

class Weapon: 
    def __init__(self, finesse=False, light=False, thrown=False, two_handed=False, 
       versatile=False): 
     props = locals() 
     props.pop('self') 
     for prop, value in props.items(): 
      if value: 
       setattr(self, prop, value) 

现在:

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 

或:

dagger = Weapon('finesse', 'light', 'thrown') 
  1. 我用我设置为False默认参数。所以如果你不提供他们 他们是False

  2. locals()为您提供了迄今为止定义的所有局部变量的字典。 在这里,这些是__init__()的参数。 由于您不想要self.self,请使用props.pop('self')将其删除。

  3. self.prop = prop does不起作用。

    例如,如果一个类A和可变x

    class A(object): 
        pass 
    x = 1 
    

    此:

    for obj in [x]: 
        A.obj = obj 
    

    给出了一个属性obj

    >>> A.obj 
    1 
    

    ,其中这样的:

    setattr(A, 'x', x) 
    

    给你一个属性x

    >>> A.x 
    1 
    

    您需要setattr(self, name, value)以编程方式设置的属性。

+0

@PeterGibson仍在努力。 ;) –

4

您可以使用**kwargssetattr

class Weapon: 
    def __init__(self, **kwargs): 
     property_list = ['finesse', 'light', 'thrown', 'two_handed', 'versatile'] 
     for prop in property_list: 
      setattr(self, prop, kwargs.get(prop, False)) 

dagger = Weapon(finesse=True, light=True, thrown=True) 

这将寻找任何属性的property_list在传递的参数,并设置该属性上self。如果该物业未找到,它将被设置为False

0

除了使用setattr设置属性,您还可以分析你ARGS成一个字典,并更新__dict__属性与它:

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = ['finesse', 'light', 'thrown', 'two_handed', 'versatile'] 
     property_values = dict([(name,eval(name)) for name in property_list]) 
     self.__dict__.update(property_values) 

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 
print dagger.finesse