C-comme des structures en Python
Est-il un moyen de définir facilement une C-structure en Python? Je suis fatigué d'écrire des trucs comme:
class MyStruct():
def __init__(self, field1, field2, field3):
self.field1 = field1
self.field2 = field2
self.field3 = field3
- Semi-par ailleurs, des types de données algébriques serait absolument merveilleux, mais bien les utiliser vous devez normalement pattern matching.
- Il n'y a rien de mal avec cette méthode, d'autres que c'est pénible à écrire?
- Vous pouvez trouver dstruct utile: github.com/dorkitude/dstruct
- plus difficile à re-facteur, sans fautes de frappe, plus difficile à lire en un coup d'oeil tandis que l'écrémage code, que
MyStruct = namedtuple("MyStruct", "field1 field2 field3")
- bien namedtuple génère une classe, c'est quoi exactement la différence?
pandas.Series(a=42).a
devrait le faire si vos données scientifique...- Passez à l'2018 réponse: stackoverflow.com/a/45426493/703382
- Votre question elle-même a le droit de répondre à "C-à l'instar des structures en Python", ou "Comment créer une structure en Python." Après avoir examiné toutes les réponses ci-dessous, je dirais que à l'aide d'une classe comme vous l'avez fait, c'est la meilleure façon de le faire. à l'Aide d'un dictionnaire est une alternative, et peut-être la deuxième meilleure façon de le faire.
Vous devez vous connecter pour publier un commentaire.
Utiliser un nommé tuple, qui a été ajouté à la les collections de module dans la bibliothèque standard de Python 2.6. Il est également possible d'utiliser Raymond Hettinger de nommé tuple recette si vous avez besoin de soutien Python 2.4.
C'est gentil pour votre exemple de base, mais couvre également un tas de bord des cas, vous aurez peut-être plus tard. Votre fragment ci-dessus devrait être écrite comme:
Le nouveau type peut être utilisée comme ceci:
Vous pouvez également utiliser les arguments nommés:
Mise À Jour: Classes De Données
Avec l'introduction de Classes de Données dans Python 3.7 nous obtenons de très près.
L'exemple suivant est similaire à la NamedTuple exemple ci-dessous, mais l'objet n'est mutable et ça permet d'avoir des valeurs par défaut.
Ce joue parfaitement avec les nouvelles en tapant module dans le cas où vous souhaitez utiliser plus d'un type spécifique d'annotations.
J'ai attendu désespérément pour cette! Si vous me demandez, Classes de Données et la nouvelle NamedTuple déclaration, combiné avec le tapant module sont un cadeau du ciel!
Amélioration de la NamedTuple déclaration
Depuis Python 3.6 il est devenu très simple et beau (à mon humble avis), aussi longtemps que vous pouvez vivre avec immutabilité.
Une nouvelle façon de déclarer NamedTuples a été introduit, ce qui permet de les annotations de type ainsi:
dataclass
module est de nouveau en Python de 3,7 mais vous pouvezpip install dataclasses
. C'est le backport sur Python 3.6. pypi.org/project/dataclasses/#description@dataclass
Les détails sont ici: pypi.org/project/dataclasses/#descriptionVous pouvez utiliser un tuple pour beaucoup de choses lorsque vous utilisez une struct en C (quelque chose comme coordonnées x,y ou RVB en couleurs par exemple).
Pour tout le reste, vous pouvez utiliser le dictionnaire, ou une classe utilitaire comme cette une:
Je pense que la version "définitive" de la discussion est ici, dans la version publiée de l'Python Cookbook.
TypeError: this constructor takes no arguments
Peut-être vous êtes à la recherche pour les Structures sans les constructeurs:
class Sample:
ne sont pas immédiatement faire n'importe quoi; ils ensemble des attributs de classe. Ceux-ci peuvent toujours être consultées que par exempleSample.name
.s1
ets2
au moment de l'exécution. Sauf interdite, vous pouvez ajouter ou modifier lesname
l'attribut de toute instance de classe à tout moment, si la classe a unname
attribut. Probablement le plus grand problème de fonctionnement est que les différentes instances de la même classe se comportent différemment selon que vous avez défininame
. Si vous mettez à jourSample.name
, tous les objets, sans définir explicitementname
propriété renvoie le nouveauname
.self
mots-clés et un constructeur de ligne, si vous me demandez. J'apprécierais si Jose pourrait modifier sa réponse pour ajouter un message d'avertissement sur le risque de accidentellement le partage de valeurs à travers les instances.Comment propos d'un dictionnaire?
Quelque chose comme ceci:
Ensuite, vous pouvez l'utiliser pour manipuler des valeurs:
Et les valeurs n'ont pas à être des chaînes de caractères. Ils peuvent être à peu près n'importe quel autre objet.
pt3.w = 1 print pt3.w
Dans une langue avec des dicts, il est préférable de les utiliser, en particulier pour les objets sérialisés, puisque vous pouvez utiliser automatiquement importer json pour les sauver et les autres sérialisation des bibliothèques, tant que vous n'avez pas de trucs bizarres à l'intérieur de votre dict. Dicts sont la solution pour garder les données et la logique distincte et sont mieux que les structures pour les personnes qui ne veulent pas écrire personnalisé serialize et unserialize fonctions et ne voulez pas utiliser de non-portable sérialiseurs comme les cornichons.Vous pouvez accéder aux champs d'une classe à l'aide d'un dictionnaire, parce que les champs d'une classe, de ses méthodes et de toutes ses propriétés sont enregistrées dans la mémoire interne à l'aide dicts (au moins dans Disponible).
...Ce qui nous amène à votre deuxième commentaire. Croire que Python dicts sont "lourds" est une manière extrêmement non-pythonistic concept. Et la lecture de ces commentaires tue mon Python Zen. Ce n'est pas bon.
Voyez-vous, lorsque vous déclarez une classe, vous créez en fait une assez complexe wrapper autour d'un dictionnaire si, si quoi que ce soit, vous ajoutez plus de ressources que par la simple utilisation d'un dictionnaire. Une surcharge qui, en passant, est dénuée de sens en tout cas. Si vous travaillez sur la performance des applications critiques, utilisez C ou quelque chose.
self['member']
est de 3 caractères de plus queself.member
, et ces personnages sont tous relativement onu-poignet de l'environnement.Vous pouvez également passer l'initialisation des paramètres pour les variables d'instance par la position
Point3dStruct
déclaration,Point3dStruct(5, 6)
ne fonctionnent pas comme prévu. Il est étrange que personne n'a écrit cela dans tous les 6 ans.print
>print()
, etattrs[n]
>next(attrs)
(filtre est maintenant son propre objet itérable et nécessitenext
).Je tiens aussi à ajouter une solution qui utilise les fentes:
Certainement vérifier la documentation de machines à sous mais une explication rapide des machines à sous est qu'il est python manière de dire: "Si vous pouvez le verrouiller ces attributs, et seulement ces attributs dans la classe, par exemple que vous engager à vous ne sera pas ajouter de tout nouveaux attributs une fois que la classe est instanciée (oui, vous pouvez ajouter de nouveaux attributs à une instance de classe, voir l'exemple ci-dessous) alors je vais le faire de suite avec les grandes allocation de mémoire qui vous permet d'ajouter de nouveaux attributs à une instance de classe et d'utiliser juste ce dont j'ai besoin pour ces fendue attributs".
Exemple d'ajout d'attributs d'instance de classe (donc pas à l'aide de fentes):
De sortie: 8
Exemple d'essayer d'ajouter des attributs à la classe de l'instance où les fentes a été utilisée:
De sortie: AttributeError: 'Point' de l'objet n'a pas d'attribut de 'z'
Ce qui peut efficacement fonctionne comme une structure (struct) et utilise moins de mémoire que d'une classe (comme un struct serait bien que je n'ai pas fait des recherches exactement combien). Il est recommandé d'utiliser les slots si vous sera la création d'une grande quantité d'instances de l'objet et n'ont pas besoin d'ajouter des attributs. D'un point de l'objet en est un bon exemple de ce qu'il est vraisemblable que l'on peut instancier beaucoup de points à décrire un ensemble de données.
Vous pouvez sous-classe de la structure C qui est disponible dans la bibliothèque standard. Le ctypes module fournit une La Structure de la classe. L'exemple de la doc:
Chaque fois que j'ai besoin d'un "instant de données objet qui se comporte aussi comme un dictionnaire" (je ne pas pense que C structs!), Je pense que de ce mignon hack:
Maintenant vous pouvez simplement dire:
Parfaitement pratique pour les moments où vous avez besoin d'un "sac de données qui n'est PAS une classe", et quand namedtuples sont incompréhensibles...
Vous accédez à C-Style struct en python manière suivante.
si vous voulez juste utiliser l'objet de cstruct
si vous souhaitez créer un tableau d'objets de cstruct
Note:
au lieu de " cstruct nom, veuillez utiliser votre struct nom
au lieu de var_i, var_f, var_str, veuillez définir votre structure est variable membre.
Quelques réponses ici sont massivement élaborés. L'option la plus simple que j'ai trouvé est (à partir de: http://norvig.com/python-iaq.html):
Initialisation:
l'ajout de plus d':
edit: Désolé de ne pas voir cet exemple déjà plus bas.
J'ai écrit un décorateur, vous pouvez l'utiliser sur n'importe quelle méthode pour faire en sorte que tous les arguments passés en, ou de toute défaillance, sont attribuées à l'instance.
Une démonstration rapide. Notez que j'utilise un de position argument
a
, utilisez la valeur par défaut pourb
, et un argument nomméc
. Je puis tout imprimer 3 de référencementself
, pour montrer qu'ils ont été correctement attribués avant la méthode est entré.Remarque que mon décorateur devrait fonctionner avec n'importe quelle méthode, et pas seulement
__init__
.Cela peut être un peu tard, mais j'ai fait une solution à l'aide de Python Méta-Classes (décorateur version ci-dessous aussi).
Quand
__init__
est appelé lors de l'exécution, il s'empare de chacun des arguments, et leur valeur et leur assigne comme les variables d'instance de votre classe. De cette façon, vous pouvez faire une struct-comme la classe, sans avoir à attribuer à chaque valeur manuellement.Mon exemple n'a pas de contrôle d'erreur, de sorte qu'il est plus facile à suivre.
Ici, il est en action.
Je posté sur reddit et /u/matchu posté un décorateur version qui est plus propre. Je vous encourage à l'utiliser, sauf si vous souhaitez étendre la métaclasse version.
Je ne vois pas de réponse ici, donc je me dis je vais l'ajouter depuis que je suis penchée Python dès maintenant et viens de découvrir il. Le Tutoriel Python (Python 2 dans ce cas) donne la suivante, simple et efficace exemple:
Qui est, une classe vide objet est créé, puis instancié, et les champs sont ajoutés dynamiquement.
Le côté, c'est vraiment simple. L'inconvénient est qu'il n'est pas particulièrement l'auto-documentation (à l'intention des membres ne sont pas répertoriés partout dans la classe "définition"), et désactiver des champs peuvent causer des problèmes lors de l'accès. Ces deux problèmes peuvent être résolus par:
Maintenant un coup d'œil, vous pouvez au moins voir ce que les champs le programme prévu.
Les deux sont sujettes à des fautes de frappe,
john.slarly = 1000
va réussir. Encore, il fonctionne.Personnellement, j'aime bien cette variante de trop. Il s'étend @dF répondre.
Il prend en charge deux modes d'initialisation (qui peut être mélangé):
Aussi, il imprime plus agréable:
La solution suivante pour une struct est inspiré par le namedtuple la mise en œuvre et certains de la réponse à la question précédente. Cependant, contrairement à la namedtuple il est mutable, dans ses valeurs, mais comme le style c struct immuable dans les noms et attributs d'une classe normale ou dict ne l'est pas.
Utilisation:
Voici une solution qui utilise une classe (jamais instanciée) pour contenir les données. J'aime que ce chemin passe très peu de dactylographie et ne nécessite pas de paquets supplémentaires etc.
Vous pouvez ajouter d'autres champs plus tard, en tant que de besoin:
Pour obtenir les valeurs, les champs sont accessibles comme d'habitude:
Il y a un paquet python exactement à cette fin. voir cstruct2py
cstruct2py
est un pur bibliothèque python pour générer les classes python à partir de code C et de les utiliser pour emballer et déballer des données. La bibliothèque peut analyser C headres (les structures, les syndicats, les énumérations et les tableaux des déclarations) et à les imiter en python. L'généré pythonic classes peut analyser et pack les données.Par exemple:
Nous avons d'abord besoin de générer le pythonic structures:
Maintenant, nous pouvons importer tous les noms à partir du code C:
Nous pouvons également le faire directement:
À l'aide de types et définit à partir du code C
La sortie sera:
Clone
cstruct2py
exécuter:Je pense que Python structure de dictionnaire est adapté à cette exigence.
https://stackoverflow.com/a/32448434/159695 ne fonctionne pas dans Python3.
https://stackoverflow.com/a/35993/159695 travaille dans Python3.
Et je l'étend à ajouter des valeurs par défaut.
Si vous n'avez pas de 3,7 pour @dataclass et la nécessité de la mutabilité, le code suivant peut travailler pour vous. C'est tout à fait auto-documenter et IDE-friendly (auto-complétion), empêche d'écrire des choses deux fois, est facilement extensible et il est très simple pour vérifier que toutes les variables d'instance sont complètement initialisé: