[python 3]
J'aime Voici un problème que je suis confronté. Je veux écrire un tableau code> code> qui héritera d'une grande partie de la fonctionnalité de Ndarray, mais n'a qu'un seul moyen d'être instancié: comme une matrice remplie zéro d'une certaine taille. J'espérais écrire: p> J'aimerais appeler Questions: P> Pourquoi Ndarray utilise-t-il des fonctions globales (module) au lieu de constructeurs dans de nombreux cas? C'est une grosse ennui si j'essaie de les réutiliser dans un cadre orienté objet. P> li>
Quelle est la meilleure façon de définir ndarray code> mais je trouve cela ennuyeux d'utiliser. P>
super () .__ init __ code> avec quelques paramètres pour créer une matrice remplie de zéro, Mais cela ne fonctionnera pas car
ndarray code> utilise une fonction globale
numpy.zeros code> (plutôt qu'un constructeur) pour créer un tableau rempli de zéro. P>
tableau de classe code> dont j'ai besoin? Devrais-je simplement remplir manuellement
ndarray code> avec des zéros ou y at-il un moyen de réutiliser la fonction
zeros code>? P> li>
ol> p>
3 Réponses :
Pourquoi Ndarray utilise-t-il des fonctions globales (module) au lieu de constructeurs dans de nombreux cas? P>
- Pour être compatible / similaire à Matlab, où des fonctions telles que
zeros code> ou
sont originaires de. li>
- Les fonctions d'usine globales sont rapides à écrire et à comprendre. Quelle devrait être la sémantique d'un constructeur, par ex. Comment afficheriez-vous un simple
zeros code> ou
vide code> ou
ou
avec un seul constructeur? En fait, ces fonctions d'usine sont assez courantes, également dans d'autres langages de programmation. LI> ol>
Quelle est la meilleure façon de définir le tableau code> que j'ai besoin? P> blockQquote>
xxx pré> Notez que c'est Python 2, mais il ne nécessiterait que de petites modifications fonctionnent avec Python 3. P> blockquote>
Quelques remarques: 1. Le paramètre code> de forme code> sur le constructeur ndarray code> peut simplement être un entier au lieu d'un tuple. 2.
dtype = flotteur code> est la valeur par défaut. 3. Dans Python 3, vous pouvez omettre les arguments sur
Super () code> dans ce cas. Combinant ces remarques, les deux premières lignes du constructeur réduisent vers
super () .__ init __ (taille) code>.
Oh, et je remarque juste que votre appel Super () code> est incorrect - devrait être
super (tableau, auto) code> dans Python 2.x.
Tu as raison, j'ai édité ma réponse. (La signature du constructeur est sans papiers, comme d'habitude.)
@Philipp: Il est documenté dans la doctrine de la classe, pas du constructeur lui-même. Mais c'est en fait où le Doc appartient.
@Sven: Ce que je veux dire, c'est que le doc) dit forme code> doit être un tuple, et ne dit pas
DTYPE code> par défaut sur
float code>.
@Philipp: Mon docstring fait i> me donne la valeur par défaut pour dtype code>. (Peut-être une version différente?) Et une forme peut Toujours I> être un tuple ou un entier, mais le DOC dit en effet "tuple d'INTS" dans ce cas.
@Sven: En effet, j'ai manqué le dtype = float code> Déclaration. En ce qui concerne
forme code>, j'ai été perplexe car le dernier exemple utilise un tuple d'un élément au lieu d'un entier.
@Philipp: Cela ne fonctionnera pas, car il n'y a pas de __ init __ code> méthode dans
ndarray code>. Je sais que dans Python 3, il tente d'appeler
objet .__ init __ code> (et échoue en raison du mauvais nombre de paramètres). Merci pour les commentaires sur le
Zeros code> Cependant, cela vous aide à comprendre d'où cela vient.
@max: C'est fait du travail i>, je l'ai testé, pas besoin de bowervote! L'appel au constructeur ndarray code> non existant est faux et je l'ai supprimé. La matrice est correctement initialisée par la méthode
__ nouvelle __ code>.
Si vous n'aimez pas NDARARRAY code> interface, ne l'héritez pas. Vous pouvez définir votre propre interface et déléguer le reste à NDARRAY et NUMPY.
import functools
import numpy as np
class Array(object):
def __init__(self, size):
self._array = np.zeros(size)
def __getattr__(self, attr):
try: return getattr(self._array, attr)
except AttributeError:
# extend interface to all functions from numpy
f = getattr(np, attr, None)
if hasattr(f, '__call__'):
return functools.partial(f, self._array)
else:
raise AttributeError(attr)
def allzero(self):
return np.allclose(self._array, 0)
a = Array(10)
# ndarray doesn't have 'sometrue()' that is the same as 'any()' that it has.
assert a.sometrue() == a.any() == False
assert a.allzero()
try: a.non_existent
except AttributeError:
pass
else:
assert 0
Très propre. Je suppose que tous les fonctions globales code> numpy code> ont la même sémantique lorsqu'ils sont appelés avec ndarray code> comme la méthode d'instance de même nom de
ndarray code>.
Pour passer à Python 3, je viens de supprimer (objet) code> de la définition de la classe, correct? [Ne pas laisser cela causerait des problèmes.]
@max: Le code fonctionne sans changement sur 2.x et Python 3.
Il me semble manquer quelque chose ici. Vous ne dérivez pas de ndarray code>, mais si un attribut est demandé, vous essayez d'abord d'obtenir l'attribut à partir de l'instance
ndarray code>. Ne serait-il pas beaucoup plus facile de tirer de
ndarray code> en premier lieu? Vous pouvez toujours ajouter la magie pour ajouter les fonctions de niveau de module en numpopie en tant que méthodes, mais je ne pense pas que ce soit une bonne idée non plus, car la plupart d'entre eux sont B> déjà des méthodes, et le reste ne avoir un sens comme une méthode (à très peu d'exceptions près).
@Sven Marnach: Le principe est que l'OP trouve ndarray code> ennuyeux à utiliser. La délégation est une approche plus flexible pour changer l'interface de classe que l'héritage. Le code n'est pas une solution finale, mais il ne s'agit que d'un simple exemple de squelette qui permet de l'étendre pour utiliser les approches de la liste de noirs, de liste blanche, etc. Je suis d'accord sur les fonctions de niveau de module. Le code montre comment i> vous pouvez le faire; Cela ne préconise pas que c'est une chose sensible à faire.
@ J.f.sebastian: Merci pour la clarification - je suis tout à fait d'accord.
L'héritage de Ndarray est un peu délicat. Au fait, pourriez-vous être plus spécifique de vos besoins particuliers? Il est toujours assez facile de cuisiner une classe (utilisation de Ndarray) pour vos propres besoins, mais une sous-classe de Ndarray pour réussir toutes les machines numériques est un problème assez différent. P>
Il semble que je ne peux pas commenter mon poteau, impair em> ndarray code> n'a même pas la méthode
__ init (auto,) ___ code>, donc il ne peut donc pas être appelé de la sous-classe, mais il y a des raisons à cela. Veuillez consulter la documentation numpy de sous-classement . P>
@Philipp: On s'appellera par Python, mais pas par NUMPY. Il existe trois façons d'instancier Ndarray et des directives sur la manière de gérer tous les cas sont donnés sur ce document. P>
Il me semble que ce document manquait. Mais pourquoi la méthode __ init __ code> dans mon exemple est appelée même si
ndarray code> avait
__ nouveau __ code>?
@Philipp: Voyez mon commentaire à votre réponse.
Je voulais juste ma propre classe que je contrôlais pleinement comment elle est instanciée. Vous avez raison de sous-classement Ndarray est trop difficile. Je suivrai l'approche du conteneur dans @ j.f. Sébastien.
Je ne vois pas pourquoi vous voulez créer votre propre cours du tout. Quel est l'avantage sur le
numpy.zeros () code> fonction d'usine? Si vous n'aimez pas le nom, il suffit de le renommer, comme
Create_array = numpy.zeros code>.
Je ne suis plus sûr qu'il y ait un avantage. Peut-être que je ne suis tout simplement pas habitué à la fonction d'usine. Je vais devoir y penser.
@Sven Marnach: J'ai trouvé plusieurs liens sur ce sujet général: Stackoverflow.com / Questions / 628950 / ... Stackoverflow.com/Questions/ 2959871 / ... Stackoverflow.com/questions/4617311/... Rien de particulier à Python, mais les commentaires généraux d'autres langues semblent appliquer. Et autant que je sache, il n'y a vraiment pas d'inconvénient pour les fonctions d'usine (autres que ma préférence personnelle).