2013-05-25 6 views
0

Je connais les propriétés de python et comment elles permettent d'utiliser un attribut classes comme avant, mais avec des modifications possibles entre les deux.Propriétés Python vs Combined Set/Get méthode

Quoi qu'il en soit, après avoir fait quelques perl récemment, je suis venu à aimer l'idée d'avoir encore moins de code et ayant getter et setter combiné

comme:

sub filename { 
    my $self  = shift; 
    my $filename = shift; 
    if ($filename){ $self->$filename = $filename;} 
    else {return $self->$filename;} 
} 

Il est évident en Perl, vous pouvez omettre le() derrière la méthode qui rend cette approche "plus propre" et plus transparente pour les utilisateurs de ma classe.

En py je pouvais faire la même le seul inconvénient étant la nécessité() lors de l'accès:

def filename(self, setter=None): 
    if setter is not None: 
     self._filename = setter 
    else: 
     return self._filename 

Pour moi, c'est juste de manière plus compacte fait alors la chose la propriété et je crois que mon code est plus lisible .

Y a-t-il quelque chose qui ne va pas dans mon approche ou est-il unidiomatique pour une raison quelconque?

Merci!

Répondre

2

Le premier problème est que l'interface est différente, et sans doute moins claire. unit.position = new_pos est transformé en unit.position(new_pos). C'est une orthographe acceptée pour une mutation dans certaines langues, mais pas tellement en Python. Presque personne ne le fait: même si property n'est pas utilisé, il existe généralement des méthodes séparées get et set. En d'autres termes, votre code ressortira comme non-idiomatique et déroutant. Par conséquent, les opérateurs d'assignation augmentée ne fonctionnent plus: unit.position += velocity n'est pas possible (cela fonctionne si .position est une propriété). Un autre problème potentiel est que cela ne prend pas en charge la définition de la propriété None. Vous devez inventer votre propre valeur sentinelle (NO_VALUE = object() etc.), rendant l'épreuve plus moche.

Le bénéfice supposé du côté de la mise en œuvre est assez faible: alors que vous enregistrez une ou deux lignes vides, vous avez besoin d'une indentation et de conditions supplémentaires. Notez que les propriétés font plus que simplement définir ou retourner (sinon, il ne devrait pas être une propriété). Propriétés (8 lignes)

@property 
def width(self, new_width): 
    self._width = new_width 
    self._dirty = True 

@width.setter 
def width(self): 
    return self._width 

par rapport méthode setter-getter (6 lignes):

def width(self, new_width=None): 
    if new_width is not None: 
     self._width = new_width 
     self._dirty = True 
    else: 
     return self._width 

Vous enregistrez une ligne vide et une ligne non-vide, mais pour que vous payez avec

  • une interface pire
  • plus indentation
  • plus de potentiel d'erreurs (par exemple faute de frappe dans un état , en oubliant else)
+0

delnan, je comprends votre point et vous avez quelque peu raison. Je vois le problème avec l'identité. Je pense juste personnellement avoir plus de méthodes = plus de lignes = plus de ballonnements et moins concis. Et quand vous avez une classe avec 10 propriétés, il devient plus difficile de garder une vue d'ensemble. Mais peut-être que c'est juste moi. :-) Merci pour votre avis! – AlessandroEmm

+0

L'opinion de @delnan est aussi à moi (+1).Les parties de python s'emboîtent de nombreuses façons cool. Si vous inventez vos propres "parties" ou expressions idiomatiques, vous perdez des fonctionnalités futures (par exemple trier des propriétés itératives ou incrémentielles) –

+0

@PhilCooper Vous avez raison, et je suis bien conscient que je vais aller de façon unidiomatique, je me demandais juste ce que les gens pensent de ces approches. En dehors d'être idiomatique il n'y a pas beaucoup de plaintes au sujet de la façon perl/scala autant que je peux voir. – AlessandroEmm

Questions connexes