如何在循环中创建类具有相同的属性

时间:2014-01-18 17:19:49

标签: python class oop

我有一个类,它有一个属性和方法(其中包括 init 等),如下所示:

Class Example(object):

    default_outputs = ['a','b','c']
    def add_outputs(self,list_of_outputs):
        return default_outputs + list_of_outputs

然后我有一个循环,它做了这样的事情:

list_of_outputs = []

for file in filelist:
    object = Example(file) 
    object.add_outputs(['d','e'])
    list_of_outputs.append(object.get_output_of_interest_which_depends_on_outputs_added)

所以你可以看到,我有这个add_outputs(['d','e'])调用循环中的每个对象 - 理想情况下我想要的是在这个特定循环中创建的每个对象都有这些输出已经指定。显然我可以将这些作为参数添加到init函数中以获得类似的东西。     object =示例(文件,['d','e'])

但这实际上是相同的,它不会与我拥有的其他方法一起使用。

所以在某种程度上我想我想要一个带有一些参数并返回另一个类的类。一个班级的班级。我怎么能用Python做到这一点?

4 个答案:

答案 0 :(得分:1)

子类是您的选项之一,例如:

Class ExampleWithDE(Example):
    def __init__(self, *args, **kwargs):
        super(ExampleWithDE, self).__init__(*args, **kwargs)
        self.add_outputs['d','e']

然后在循环中使用这个新类:

for file in filelist:
    object = ExampleWithDE(file)
    ...

答案 1 :(得分:1)

我将专注于你问题的这一部分:

  

所以在某种程度上我想我想要一个带有一些参数并返回另一个类的类。一个班级的班级。我怎么能用Python做到这一点?

你正在寻找的东西叫做MOP,即元对象协议,也称为反射(有点,我猜不完全正确)。这个协议是一组函数和数据结构,它们向程序员描述对象系统本身(所以你有像Class对象之类的东西)。

http://eli.thegreenplace.net/2011/08/14/python-metaclasses-by-example/

但是你也可以从一个在初始化时做这种事情的基类继承,如下所示:

Class ext(Example):
    def __init__(self, *args, **kwargs):
        super(ext, self).__init__(*args, **kwargs)
        self.add_outputs["d", "e"]
编辑:修正了一些东西,看到我的答案的第二部分已经由其他人提供,抱歉。

答案 2 :(得分:1)

动态创建一个类并不复杂:

def extends_example_with(outputs):
   class ExtendedExample(Example):
       default_outputs = Example.default_outputs + outputs

   return ExtentedExample

cls = extend_example_with([d, e])
for file in filelist:
  object = cls(file)

答案 3 :(得分:0)

编辑1

以下不是你想要的吗?

class Example(object):
    default_outputs = ['a','b','c']
    def __init__(self,x):
        self.x = x
    @classmethod
    def add_outputs(cls,list_of_outputs):
        cls.used_output = cls.default_outputs + list_of_outputs
    def get_output_of_interest(self):
        return ''.join(self.x*y for y in self.used_output)

list_of_outputs = []
filelist = (1,3,6)
Example.add_outputs(['e','hy'])
for file in filelist:
    obj = Example(file)
    list_of_outputs.append(obj.get_output_of_interest())
print list_of_outputs

print '================'

list_of_outputs = []
filelist = (5,2)
Example.add_outputs(['d','G'])
for file in filelist:
    obj = Example(file)
    list_of_outputs.append(obj.get_output_of_interest())
print list_of_outputs

结果

['abcehy', 'aaabbbccceeehyhyhy', 'aaaaaabbbbbbcccccceeeeeehyhyhyhyhyhy']
================
['aaaaabbbbbcccccdddddGGGGG', 'aabbccddGG']

很明显,我们定义了__init__get_output_of_interest方法的代码,以便为我提供一个可执行代码,该代码显示在每个类之前设置了名为used_output的类属性循环迭代。
这样做,可以在每次循环迭代之前设置此属性以及对象filelist,并且在循环之后获得的结果也依赖于filelist的值,就像此类属性{{1}一样无需为循环内的每个创建对象设置它。

您可能会对此文档的摘录感兴趣:

  

一个类实例有一个名称实现为字典的名称空间   搜索属性引用的第一个位置。当一个   在那里找不到属性,并且实例的类有一个   通过该名称的属性,搜索继续该类   属性。   http://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy

原始答案

您的问题很模糊,因为反复对一个唯一标识符进行分配不会让您访问多个对象,只能访问最后创建的对象。

但首先,您的代码有三个问题让我怀疑您是否试图执行它:

  • 在类的定义中是used_output,而不是class

  • Class产生错误,因为没有Example(file)方法来接收参数

  • 使用__init__作为标识符会覆盖对名为object的基本内置对象的访问

现在展示我在开头说的话:

object

结果

class Example(object):
    default_outputs = ['a','b','c']
    def add_outputs(self,list_of_outputs):
        return default_outputs + list_of_outputs

filelist = (0,1,2,3,4,5)

for file in filelist:
    obj = Example()
    print 'id of obj :',id(obj)

如果您想要访问创建的第一个对象,您会怎么做? ,因为第一个对象具有标识18632816并且使用标识符id of obj : 18632816 id of obj : 18603984 id of obj : 18632816 id of obj : 18603984 id of obj : 18632816 id of obj : 18603984 可以访问具有标识18603984的对象!

标识是18632816和18603984的标识是由于以下事实:当重新分配标识符obj时,前一个绑定被破坏,前一个对象在RAM中丢失,然后该过程重新使用RAM的相同部分用于创建重新分配给相同标识符的新对象。

以下代码更清楚地显示了实际发生的情况:

obj

结果

class Example(object):
    default_outputs = ['a','b','c']
    def add_outputs(self,list_of_outputs):
        return default_outputs + list_of_outputs

filelist = (0,1,2,3,4,5,6,7)

li = []

for file in filelist:
    obj = Example()
    li.append(obj)
    print 'id of obj :',id(obj)

这次,对每个已创建对象的访问权限不会丢失,因为可以通过列表id of obj : 18632816 id of obj : 18603984 id of obj : 18633680 id of obj : 18743632 id of obj : 18743504 id of obj : 18743664 id of obj : 18743696 id of obj : 18743728 <__main__.Example object at 0x011E01B0> 的索引进行访问。
但是使用标识符li访问的对象是最后创建的对象,而且只有这一个。 011E01B0是adress的十六进制值==用obj访问的对象的标识,如果你用十进制值变换它,你会找到18743728

那么你想做什么呢?