2017-10-04 1 views
1

Je veux créer une classe enfant de liste qui peut convertir tous les éléments automatiquement en un objet quel que soit l'élément créé par init ou ajouter ou étendre. Donc, en utilisant à la fois pour la boucle ou getitem. Voici un exemple de code simple. Quel genre de méthode magique devrais-je utiliser?Comment convertir tous les éléments automatiquement dans une liste en un objet donné en Python

class A(): 
    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return 'Object A with name {}'.format(self.name)  

class CustomerList(list): 
    def __init__(self, *args): 
     super(CustomerList, self).__init__(*args)   

c = CustomerList('a') 
c.append('b') 
c[0] # Object A with name a 
c[1] # Object A with name b 
for ele in c: 
    print(c) 
# Object A with name a 
# Object A with name b 
+0

Que voulez-vous dire en convertissant l'élément en objet? Techniquement, tout est un objet. – TerryA

+0

@TerryA convertit évidemment n'importe quel objet en un objet de type donné, Typiquement, l'objet A dans cet exemple, tout convertir en A. –

+1

Il n'y a aucune méthode magique qui ferait le travail. Vous devez surcharger '__init__',' __setitem__'. "append", "extend", et probablement quelques autres auxquels je ne pense pas pour le moment. – jasonharper

Répondre

2

vous demandent comment passer outre __append__?

class A(): 
    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return 'Object A with name {}'.format(self.name)  

class CustomerList(list): 
    def __init__(self, *args): 
     super(CustomerList, self).__init__(*args) 
    def append(self,letter): 
     super(CustomerList, self).append(A(letter)) 

je suppose ??? .. mais comme mentionné dans les commentaires si vous voulez

my_custom_list.extend(["A","B","V"]) 
my_custom_list[2] = "A" 

pour travailler, vous devrez passer outre

def __setitem__(self,key,value): # cover a[2]='A' 
    super(CustomerList,self).__setitem__(key,A(value)) 

def extend(self,other): 
    super(CustomerList,self).extend([A(val) for val in other]) 

vous alors probablement besoin grossier de surcharger __add__,__iadd__ au minimum également

+0

Comment faire pour convertir avec le cas d'initialisation? et d'ailleurs, si je veux ajouter ajouter donc je dois remplacer toutes les méthodes? –

+0

Toutes ces actions traitent du comportement d'entrée d'une liste. Pouvons-nous utiliser une méthode magique pour contrôler la sortie de la liste. Par exemple, je ne me soucie pas du type réel dans cette liste tant que je retire un élément, il peut être converti en type attendu. –

+0

vous pouvez utiliser '__getitem__' peut-être –

1

Je pense que ce que vous essayez de faire est: lorsque vous ajoutez un nouvel élément dans la liste, il est un objet de classe A. Qu'est-ce que vous pouvez faire est override list.append:

class A(): 
    def __init__(self, name): 
     self.name = name 
    def __repr__(self): 
     return 'Object A with name {}'.format(self.name)  

class CustomerList(list): 
    def __init__(self, *args): 
     super(CustomerList, self).__init__(*args) 
    def append(self, arg): 
     new_obj = A(arg) 
     self.insert(len(self), new_obj) 
+0

réponse raisonnable ... bien que je pense que l'insertion est O (N), tandis que append est O (1) ... je pense (+1 tout de même) –

+1

@JoranBeasley Assez juste. J'ai juste supposé que vous ne pouviez pas utiliser la fonction précédente append si vous la surchargiez, mais vous m'avez prouvé le contraire: P – TerryA

+0

Comment convertir avec le cas d'initialisation? et d'ailleurs, si je veux ajouter ajouter donc je dois remplacer toutes les méthodes? –