2012-08-15 101 views
1

我的问题是如何在运行中创建变量。我试图用随机的一组属性来生成一个对象。Python - 动态变量

from random import randint, choice 

class Person(object): 
    def __init__(self): 
     self.attributes = []  

possible_attributes= ['small', 'black', 'scary', 'smelly', 'happy'] # idk, random 
chance = randint(1,5) 

chosen_attributes = [] 
for i in xrange(chance): 
    #psuedo code... 
    local_var = choice(possible_attributes) 
    if local_var not in chosen_attributes: 
     VAR = local_var # VAR needs to be dynamic and 'global' for use later on 
     chosen_attributes.append(local_var) 
     Person.attributes.append(local_var) 

我敢肯定我怎样,我想这样做,这不是一个好办法,所以如果有人明白我在寻找,并能够提供更好的方法(一个工程,对于初学者)我将是最感激。谢谢!

+3

这是...非常烂。改用字典。 – 2012-08-15 04:19:23

+0

为什么你需要VAR是'全球'?构建具有所有期望属性的Person实例有什么问题? – 2012-08-15 04:20:40

+0

我认为这个问题是你需要弄清楚如何避免这种情况。字典和列表做了很棒的工作。 – 2012-08-15 04:24:17

回答

1

添加属性的类的实例可以使用.__dict__

class Person(object): 
    def addattr(self,x,val): 
     self.__dict__[x]=val 

输出:

>>> a=Person() 
>>> a.addattr('foo',10) 
>>> a.addattr('bar',20) 
>>> a.foo 
10 
>>> a.bar 
20 
>>> b=Person() 
>>> b.addattr('spam','somevalue') 
>>> b.spam 
'somevalue' 
+1

更简单的就是使用'setattr()'。 – Duncan 2012-08-15 11:21:32

0

这是怎么了,我可能构造对象与一组随机属性,给定你的定义:

import random 

possible_attributes= ['small', 'black', 'scary', 'smelly', 'happy'] 

class Person(object): 
    def __init__(self): 
     self.attributes = random.sample(possible_attributes, random.randint(0, len(possible_attributes))) 

这会从您的可能属性列表中选择一个随机数的属性。

>>> print Person().attributes 
['small', 'smelly'] 
>>> print Person().attributes 
['scary', 'smelly', 'happy'] 
0

通常,不要污染全局命名空间,您不希望添加到全局变量。字典提供了一个命名空间般的方式来访问的一切,但如果你真的要使用全局变量()[X] =一些修改的项目,或者使用很讨厌

exec "var_name=somehting" 
+1

我会高度暗示_against_使用'exec',除非你_really_ - 不,**真的** - 知道你为什么需要它。 – voithos 2012-08-15 04:22:44

+0

这就是为什么我说“讨厌”的原因 – 2012-08-15 04:23:19

+1

事实:exec会减慢你的整个程序,因为Python必须关闭一些本来可以做的优化。 – 2012-08-15 04:25:47

1

使用vars。例如:

>>> import math 
>>> class foo: pass 
>>> vars(foo) 
{'__module__': '__main__', '__doc__': None} 
>>> vars(foo)['fn']=math.sin 
>>> foo.fn(2) 
0.9092974268256817 
>>> vars(foo) 
{'__module__': '__main__', '__doc__': None, 'fn': <built-in function sin>} 

正如你所知,方法只是带有一个参数的函数。

1

尽管我不能确切地告诉你需要什么,但我猜测你实际上并不需要全局变量,只有一个具有随机/动态属性集的Person对象。对于这一点,你要setattrrandom.sample()

crazy_person = Person() 
selected_attribute_names = random.sample(possible_attributes, 3) 
for attribute_name in selected_attribute_names: 
    setattr(crazy_person, attribute_name, True) 

# optional -- if you want to have a list of attributes, just copy that in: 
crazy_person.attributes = selected_attribute_names 
# vars(crazy_person).keys() will give you more or less the same thing though, for free 

# hasattr(crazy_person, 'small') will tell you if you picked 'small' 
# if we chose 'small', then from here on, crazy_person.small will be True as well 
1

嗯林不知道你是什么绑在这里实现,但可能有几件事情在这里下车....

class Person(object): 
    def __init__(self): 
     self.attributes = [] 

这定义一个类对象,您可以从中创建包含attributes的对象,如我们从__init__或构造函数可以看到的那样在其他语言中调用该对象。

,但你必须

Person.attributes.append(local_var) 

这里Person是一个类的对象真的不具备的属性是哪里定义,因为不只是从这个类创建的对象......

可以创建一个新人并向他们添加适当的属性。

>>> me = Person() 
>>> me.attributes.append('humble') 

其次我们真的不应该直接访问属性,因为任何东西都可以附加到列表中,包括重复的属性。

为什么不简单地添加一个添加属性的函数。

class Person(object): 
    def __init__(self): 
     self._attributes = [] # note any variable starting with _ is meant to be private 
    def add_attribute(attribute): 
     if attribute not in self._attributes: 
      self._attributes.append(attribute) 

如果性能是我们可以利用的set()代替[],因为它不允许重复条目和真快检查任何查找的缺点是值必须散列能即字符串或关注整数或其他简单的数据类型...

+0

对。这只是伪代码。我想尽量简短,但我不知道,谢谢你花时间通知我! :)我在其他帖子中一直不太简短,所以我这次做了一个努力,并反过来投票发布了一些看起来不太好的东西......我可能会避免从现在开始在这里张贴。 (我为随机咆哮道歉,我现在脾气暴躁) – jtsmith1287 2012-08-15 05:11:14