6
votes

Attribut ou méthode?

J'écris un script Python qui calcule diverses quantités basées sur deux paramètres, le rayon long et le rayon court d'un sphéroïde. Cela m'est arrivé que je pouvais écrire une classe sphéroïde pour le faire. Cependant, je suis nouveau dans la conception orientée et la merveille si vous pouvez m'aider.

Une instance est instanciée avec les paramètres A et B pour le rayon long et le rayon court respectivement, donc j'ai conçu la classe comme suit: p> xxx pré>

une des quantités Je veux calculer est le volume. Le volume d'un sphéroïde est 4 * pi / 3 * a * b * b. P>

Ma question est, est-ce que je définis une méthode ou un attribut pour cela dans ma classe? P>

E.g. Je pourrais définir une méthode: p> xxx pré>

ou je pourrais simplement utiliser un attribut: p> xxx pré>

je pourrais aussi l'inclure simplement Dans la méthode init: p> xxx pré>

meilleur à utiliser et pourquoi? En général, quand j'utiliserais une méthode et quand j'utiliserais-je un attribut? Je ne me soucierais pas normalement, mais j'ai une charge entière à mettre en œuvre et j'aimerais avoir une idée de la conception de OO pour une référence future. P>

Merci P>

EDIT: P>

Après la mise en œuvre de propriétés conformément à la suggestion de Martijn, j'ai fini par quelque chose comme ceci: P>

class Spheroid(object):
  def __init__(self,a,b):
    self.shortax = a
    self.longax  = b
    self.alpha=self.longax/self.shortax

    @property
    def volume(self):
        return (4*np.pi/3) * self.shortax * self.shortax * self.longax

    @property
    def epsilon(self):
        return np.sqrt(1-self.alpha**(-2))

    @property
    def geometricaspect(self):
        return 0.5 + np.arcsin(self.epsilon)*0.5*self.alpha/self.epsilon

    @property
    def surfacearea(self):
        return 4*np.pi*self.shortax**2*self.geometricaspect


1 commentaires

Excellente question. Notez que les compromis sont dépendants de la langue. Une réponse pourrait être évidente en C ++ avec une réponse différente en Python.


3 Réponses :


9
votes

Vous avez une 3ème option: faites-le à la fois un attribut et une méthode, en utilisant un propriété : xxx pré>

vous accédez .volume code> comme un attribut: p>

>>> s = Spheroid(2, 1)
>>> s.volume
8.377580409572781
>>> s.volume = 75.39822368615503
>>> s.long, s.short
(2, 3.0)


12 commentaires

Vous voudrez peut-être mentionner qu'un autre avantage est que volume est également "en lecture seule".


@Jonathanvanasco: C'est la prochaine étape; Ce n'est pas une exigence :-)


Salut Martijn, merci pour votre message. Pouvez-vous expliquer pourquoi la définition d'une propriété est meilleure que d'utiliser une méthode? Avec une méthode, je retardais également le calcul du volume jusqu'à ce que j'appelle la méthode, non?


@ user1654183: C'est un choix stylistique. L'attribut cache le fait qu'il s'agit d'un calcul et que vous ne pouvez pas lui donner des arguments (vous auriez toujours besoin d'une méthode si des arguments sont nécessaires).


@ user1654183: autre que cela, puisque une propriété est vraiment une méthode, il n'y a pas de différence. Si vous avez eu besoin d'un getter et un setter (donc .get_volume () et set_volume () où ce dernier ajuste soit auto.hort ou self.long pour rendre l'ajustement sphéroïde, par exemple), une propriété brille vraiment.


Être capable de changer longtemps et court en fonction du volume serait vraiment utile. Je dois d'abord lire un peu plus dans cette entreprise de propriété. Merci!


Je vais l'accepter sous peu - je reçois un attributError chaque fois que j'essaie quelque chose comme S.Volume, veuillez vous reporter à mon édition. Des idées?


@ user1654183: une erreur d'attribut in la propriété sera masquée comme une erreur d'attribut pour la propriété. C'est self.shortax , etc.


@ user1654183 Je considère que l'expression "rendez-la à la fois un attribut et une méthode" d'être incorrecte. Tout d'abord, parce que attribut est un mot générique qui couvre toutes sortes de membres de l'espace de noms d'un objet: "d'ailleurs, j'utilise l'attribut Word pour n'importe quel nom suivant un point" Aide et "là-bas sont deux types de noms d'attributs valides, d'attributs de données et de méthodes " Doc


@eyquem: Je suis tout à fait d'accord; ajouté une pièce courte à la fin pour qualifier la terminologie.


@ user1654183 Deuxièmement, parce que Martjin signifie en fait "le rendre à la fois un attribut de données et une méthode" mais il est toujours incorrect comme celui-ci, car un attribut de propriété est en réalité une méthode, du point de vue de la Mise en œuvre, pas un attribut de données. La saveur d'attribute d'une propriété est située dans la manière dont elle s'appelle: utiliser la notation d'attribut. Donc, il ne faut donc pas faire de la confusion entre une notation d'attribut et la nature d'attribut d'un objet. Imo


@ user1654183 Cependant, je vous évite cette réponse, car il explique bien pourquoi la création de volume une propriété de l'objet est meilleure: le calcul est effectué uniquement en cas de besoin, et plus important pour moi: les valeurs de MORTAXE, longAXe et volume sont toujours gardés cohérents



2
votes

utiliseras-tu toujours ces données?

Sinon, vous pouvez utiliser une propriété, puis le calculez de manière paresseusement ... xxx


4 commentaires

Si vous modifiez self._volume = ... à self.volume = ... , alors vous évitez les appels de fonction ultérieurs.


@ Robᵩ en Python2.7, que j'utilise, il soulève un attributError. [Et j'ai souhaité si souvent que je pouvais faire ça]


@ Robᵩ: Non, vous ne pouvez pas. Les descripteurs de données (comme une propriété) sont d'abord recherchés sur la classe et ne peuvent pas être remplacés par un attribut d'instance.


Vous êtes tous les deux corrects, j'avais tort. J'ai testé avec des classes de style ancien, quel test n'était pas valide. Merci.



1
votes

Je voudrais mettre en œuvre le volume comme méthode en raison des éléments suivants:

  1. Il peut être calculé à partir d'autres attributs. Il enregistre donc de l'espace pour le calculer (à moins que ce soit un calcul très compliqué et que vous ne pouvez envisager de la mettre en cache)
  2. Ce n'est pas une "fonctionnalité" naturelle de l'objet, par exemple pour cercle le rayon est un attribut mais pas la zone (ce n'est pas vraiment la définition de format)
  3. Quelque chose comme le volume est une sorte de méthode abstraite, si vous souhaitez avoir une famille d'objets et calculer le volume de chacun d'entre eux sous forme polymorphe.

2 commentaires

Pouvez-vous élaborer sur l'argument "Saves Space"?


Si vous le sauvegardez comme champ, vous avez un entier supplémentaire par objet