9
votes

Cours d'auto-référencement dans Python?

en Python, pouvez-vous avoir des cours avec des membres qui sont eux-mêmes des pointeurs aux membres du type de la même classe? Par exemple, dans C, vous pourriez avoir la classe suivante pour un nœud dans un arborescence binaire: xxx

Comment créeriez-vous cela de manière équivalente à python?


9 commentaires

Ce sont des pointeurs vers la classe, pas la même classe. Vous ne pouvez pas avoir une classe avec des membres de son propre type dans n'importe quelle langue. C'est une récursion infinie.


Tu as raison. Mes excuses. La question est toujours pertinente, cependant.


Ce n'est pas vrai, consultez un simple échantillon de liste liée en Java: Stackoverflow.com/Questtions/354875/...


@ ridecar2, ces champs sont des pointeurs vers des objets sur le tas.


@Joshd: Vous êtes correct, à l'exception de la partie "du tout dans n'importe quelle langue". Types de données récursifs sont en fait tout à fait possible dans de nombreuses langues fonctionnelles - c'est comment Haskell implémente les listes liées , par exemple. Cependant, pour que cela fonctionne correctement, vous devez utiliser une sorte de type syndical (afin que vous puissiez définir votre cas de bord) ou utiliser une évaluation paresseuse.


@Daniel Pryden, regardez le deuxième exemple sur cette page que vous avez liée à.


@ ridecar2, @Daniel Pryden: Mon libellé n'était pas exact. Dans ce que j'ai dit, cela peut être compris comme incorrect. Ma signification était plus du point de vue de la mise en page de la mémoire: une structure réelle de la mémoire ne peut être contenue en elle-même. Dans quelque chose comme Java, les références ou les pointeurs prennent soin de cette affaire, ce qui est beaucoup ce que la structure dans la question est en cours. Je ne voulais pas dire que le concept de données récursif était impossible (c'est ce qu'un nœud d'arbre binaire est après tout :))


@ ridecar2: Il semble que nous sommes d'accord, pas en désaccord. Les types de données récursifs peuvent et existent. Je ne suis pas sûr que j'accepte que l'exemple Java est un bon, car les variables de type Java de type objet sont nullables, tandis que les instances d'objet elles-mêmes ne peuvent pas être nulles et ne sont donc techniquement pas du même type (dans un sens théorique de type). Étant donné que Java n'expose aucun mécanisme pour faire référence au type d'instance réel d'objets (par opposition aux types de référence qui les renvoyer), les variables auto-référentielles en Java sont en fait des références, non contrairement aux pointeurs de l'exemple de C dessus ci-dessus.


@Joshd Nope, la référence Python est comme un pointeur. Dites quand vous l'utilisez pour un type d'argument, peu importe ce qu'il contient.


7 Réponses :


8
votes

Python est une langue dynamique. Les attributs peuvent être liés à (presque) à tout moment avec n'importe quel type. Par conséquent, le problème que vous décrivez n'existe pas dans Python.


7 commentaires

Hein? Cela n'a pas répondu à la question de l'OP "" "Comment créeriez-vous cela de manière équivalente à Python?" ""


@John Machin: Évidemment, l'OP pensait que cela a fait, puisqu'il a accepté la réponse. :)


@John: Bien qu'il ait écrit «Comment créeriez-vous cela de manière équivalente à Python? La réponse, bien sûr, est que vous ne le faites pas, car vous n'avez pas besoin de python.


@MusicFreak: "Évidemment" ??? La souris de l'OP a cliqué sur le bouton "Tick" - cela ne prouve ni pensé ni acceptation.


@Ignacio: Vous acheminez l'OP? Ou travaillez-vous à l'envers de votre réponse pour dériver la question?


@John: Les années de soutien à l'IRC vous apprendent que les gens ne posent pas toujours la question qu'ils veulent répondre.


Il y a des problèmes dans l'annotation de type. (Ensuite, Google m'a conduit ici)



9
votes

Émulation d'une structure C en Python (à l'aide de STR au lieu d'INT en tant que type de données):

"Déclaration": p>

root = Node()
root.data = "foo"

b = Node()
b.data = "bar"
root.left = b

z = Node()
z.data = "zot"
root.right = z


8 commentaires

Vous déclarez des membres de la classe ici, pas des membres d'instance, n'est-ce pas?


Désolé, quelqu'un peut-il s'il vous plaît expliquer le commentaire ci-dessus?


@AMSSAGE: Vous voudrez peut-être consulter les réponses à cette autre question et / ou lisez la page du Tutoriel Python sur les classes .


@Russell Borogove: Qu'avez-vous jamais réalisé?


Ces instances héritent de variables de classe. Je pense que j'ai rencontré un comportement déroutant lorsque j'apprendais d'abord Python Oo et je viens d'éviter d'utiliser des variables de classe entièrement depuis lors. J'ai configuré toute mes instance par défaut dans init .


La confusion probablement causée par l'utilisation d'une valeur mutable. Et ils ne sont pas "variables" en ce qui concerne l'instance jusqu'à ce que l'instance change. Cela signifie que vous pouvez avoir un tas de «constantes de classe», y compris des listes, des dictes, des ensembles qui traitent des informations de référence en lecture seule. Le bonheur prévaut si longtemps que vous obéissez au «pique-ci mais ne manquez pas».


@Russell Borogove: En tant qu'instance d'une borogove, vous pouvez peut-être nous éclairer sur ce que Lewis Carroll signifiait par "Mimsy" :-)


Un mot de Portmanteau alliant «misérable» et «fragile». alice-in-wonderland.net/school/alice1019.html



1
votes

http://code.activestate.com/recipes/286239-binary - L'arborescence / est un échantillon d'arbre binaire créé à l'aide de cette structure.


0 commentaires

2
votes

Comment pourrais-je créer de manière équivalente cela dans Python? XXX

Étant donné que toutes les variables python sont, en vigueur, des références sans faille, vous n'avez pas à mentionner à l'avance à gauche et à droite. être des instances de nœuds.


0 commentaires

3
votes

Vous ne pouvez pas déclarer des types de python - par conséquent, il n'y a pas de problèmes déclarant des types de python.


0 commentaires

7
votes

Bien que cela puisse indiquer que d'autres réponses signalées, ce n'est pas un problème dû à la dynamique de frappe, en fait, pour Python3, il s'agit d'une question très réelle en matière d'annotations de type . Et cela ne fonctionnera pas (notez une annotation de type de l'argument de méthode): xxx

résultats: xxx

plus sur la nature de la nature Un problème ici: https://www.python.org/ Dev / PEPS / PEP-0484 / # THE-PROBLÈME DÉCLARATIONS-DÉCLARATIONS

Vous pouvez utiliser des littéraux de chaîne pour éviter les références en avant

 Entrez la description de l'image ici

Autre moyen n'utilise pas l'annotation de type de style Python3 dans de tels cas,

et c'est le seul moyen si vous devez garder votre code compatible avec plus tôt Versions de Python.

Au lieu de cela, pour obtenir une autocopompetion dans mon IDE (Pycham), vous pouvez comme ceci:

 à l'aide de Python Docstrings au lieu de taper les indices pour éviter une Classe auto-référencée

mise à jour: Alternativement, au lieu d'utiliser Docstrings, vous pouvez utiliser "Type:" Annotations dans un commentaire . Cela garantira également que la vérification du type statique MyPY fonctionnera (MyPY ne semble pas se soucier de Docstrings):

 Entrez la description de l'image ici


3 commentaires

Merci! C'est mon problème alors Google m'a conduit ici.


Une autre alternative: Définissez une classe vide_name: Pass précédemment.


L'idée d'annotation str est génie !!!!!!!!! esp. pour certains types seulement utilisés.



1
votes

Cette question mérite une refonte pour 2021. Faisons un certain code puis traverse une panne. XXX

AS de Python 3.7, nous avons EPP 563 - Évaluation différée des annotations , ce qui signifie que l'on peut utiliser des indications de type pour référencer la classe, à l'intérieur de la classe. Il faut être activé, c'est-à-dire notre première ligne de code.

Le @DataClass Decorator fait partie du Classes de données , a également ajouté en 3.7 et nous donne un moyen pratique de définir une classe, en particulier celle qui est principalement des définitions de membres.

J'ai utilisé noeud plutôt que noeud , car les noms de classe sont généralement capitalisés en python, à Évitez la collision avec des variables et des modules. Ceci est une chose stylistique et peut être ignoré en toute sécurité la plupart du temps.

Enfin, de Python 3.10, vous pouvez supprimer le à partir de __future __... Importer comme il sera activé par défaut. La date de sortie pour cela est ... Oh, c'est aujourd'hui!


0 commentaires