2016-01-31 6 views
1

Я хочу построить класс, который в основном представляет собой массив объектов. Я хочу, чтобы этот класс возвращал мне список атрибутов его членов. Например, из класса:Атрибуты доступа к списку объектов с использованием класса

class Animal(): 
    def __init__(self, height, age): 
     self.height = height 
     self.age = age 

dog = Animal(1,2) 
cat = Animal(3,4) 

Я хочу создать класс группу, которая будет делать:

my_group = Group([dog,cat]) 
print(my_group.height) #return [1,3] or (1,3) or array([1,3]) 

Я думал делать:

import inspect 

def get_attribute(instance): 
    """Return all attributes of an instance (except all internal built-in)""" 

    attributes = inspect.getmembers(instance, lambda a:not(inspect.isroutine(a))) 
    return [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))] 

class Group(): 
    def __init__(self, members): 
     self.members = members 

     attributes = [a[0] for a in get_attribute(list(members)[0])] #assuming members are all of the same class 

     for a in attributes: 
      setattr(self, a, [getattr(m, a) for m in self.members]) 

можно затем использовать группу для других классов, например:

class Human(): 
    def __init__(self, name, weight): 
     self.name = name 
     self.weight = weight 

class Family(Group): 
    pass 

alan = Human("alan", 1) 
bob = Human("bob", 2) 
my_family = Family([alan, bob]) 
print(my_family.weight) #returns [1, 2] 

Это работает, но кажется неэффективным, если число членов становится очень высоким, так как оно накладывается на каждого члена. В принципе, мой код работает, но я хотел бы ускорить его работу с помощью таких функций, как карта или что-то подобное.

ответ

1

использовать атрибут класса:

class Animal(): 
    all_data = {"height":[],"age":[]} 
    def __init__(self, height, age): 
     self.height = height 
     self.age = age 
     Animal.all_data["age"].append(age) 
     Animal.all_data["height"].append(height) 

dog = Animal(1,2) 
cat = Animal(3,4) 


print(Animal.all_data["height"]) 
print(Animal.all_data["age"]) 
+0

Это то, что называют другие языки * static * –

+0

С вашим решением мне нужно определить all_data для каждого класса, в котором я хочу это поведение (Animal, Human и другие). Кроме того, мне все равно нужно добавлять значения в список, который не является желаемой функцией, поскольку у меня много объектов. – ldocao

+0

@idoco, вам не нужно определять его для каждого класса, вы определяете его один раз и используете его в каждом классе, если вы не хотите хранить все данные, тогда вы должны итерации, вы можете обернуть каждый класс с помощью функция для добавления, если это больше нравится. –

0

Может быть, вы можете просто определить метод, чтобы сохранить его динамический:

class Animal(): 

    def __init__(self, height, age): 
     self.height = height 
     self.age = age 

dog = Animal(1,2) 
cat = Animal(3,4) 

class Group(): 
    def __init__(self, members): 
     self.members = members 

    def get_all_attr(self, a): 
     return [getattr(m,a) for m in self.members] 

my_group = Group([dog,cat]) 
print(my_group.get_all_attr("height")) #returns [1,3] 

Я не думаю, что вы можете уйти без зацикливания над членами каждый если вы используете ленивую инициализацию.

+0

Спасибо за сообщение, но это именно та проблема, о которой я прошу ответа – ldocao