Dynamiquement la définition des champs d'instance dans les classes Python
Je suis Python provenant principalement de programmation Java.
Je suis actuellement en train de réfléchir sur la façon dont les classes en Python sont instanciés.
Je comprends que __init__()
: c'est comme le constructeur en Java. Cependant, parfois, les classes python n'ont pas de __init__()
méthode qui, dans ce cas, je suppose, est un constructeur par défaut tout comme en Java?
Une autre chose qui rend le passage de Java, python légèrement difficile, c'est qu'en Java, vous devez définir tous les champs d'instance de la classe avec le type et parfois une valeur initiale. En python tout cela semble disparaître et les développeurs suffit de définir de nouveaux champs à la volée.
Par exemple je suis tombé sur un programme comme suit:
class A(Command.UICommand):
FIELDS = [
Field( 'runTimeStepSummary', BOOL_TYPE)
]
def __init__(self, runTimeStepSummary=False):
self.runTimeStepSummary = runTimeStepSummary
"""Other methods"""
def execute(self, cont, result):
self.timeStepSummaries = {}
""" other code"""
La chose qui confond (et légèrement irritant pour moi) est que cette classe n'a pas un champ appelé timeStepSummaries encore comment un développeur peut-il, au milieu d'une méthode, il suffit de définir un nouveau champ? ou est ma compréhension incorrecte?
Donc, pour être clair, ma question est en Python peut-on définir dynamiquement de nouveaux champs d'une classe en cours d'exécution, comme dans cet exemple ou est-ce timeStepSummaries variable d'une instance de java comme variable privée?
EDIT: j'utilise python 2.7
Merci pour le livre de référence.
classes à travailler de la même manière dans python 2 vs 3 de sorte que vous devrait préciser que nous parlons ici.
J'utilise python 2.7. Il est maintenant ajouté à ma question initiale.
OriginalL'auteur SeekingAlpha | 2014-02-02
Vous devez vous connecter pour publier un commentaire.
Pour être plus précis, en Python
__new__
est la méthode constructeur,__init__
est l'initialiseur. Lorsque vous neSomeClass('foo', bar='baz')
, letype.__call__
méthode ne fond:Généralement, la plupart des classes de définir une
__init__
si nécessaire, tout en__new__
est plus communément utilisé pour des objets immuables.Je ne suis pas sûr de vieux-classes de style, mais c'est le cas pour les nouveau-style:
Si explicite pas
__init__
est définie, la valeur par défaut sera appelée.Oui.
Attributs peuvent être ajoutés à une instance à tout moment:
Cependant, il est possible de restreindre l'instance d'attributs qui peuvent être ajoutées par le biais de l'attribut de classe
__slots__
:(C'est probablement important de noter que
__slots__
est principalement conçu comme un optimisation de la mémoire - en n'exigeant pas un objet disposer d'un dictionnaire pour stocker les attributs - plutôt que comme une forme d'exécution de la modification de la prévention.)OriginalL'auteur Matthew Trevor
Attributs des objets Python sont généralement stockés dans un dictionnaire, tout comme ceux que vous créez avec
{}
. Puisque vous pouvez ajouter de nouveaux éléments à un dictionnaire, à tout moment, vous pouvez ajouter des attributs à un objet à tout moment. Et depuis tout type d'objet peut être stockée dans un dictionnaire sans précédent de la déclaration de type, tout type d'objet peut être stockée dans un attribut d'un objet.En bref,
my_object.abc = 42
est (souvent) juste un raccourci pourmy_object.__dict__["abc"] = 42
.Il est possible de définir les objets sans
__dict__
par la définition de la__slots__
attribut, ou de remplacer certaines méthodes spéciales et stocker les attributs d'une autre façon, bien que la plupart du temps, vous ne devriez pas le faire.__mro__
avant de pouvoir passer à l'instance dict (si présent). Aussi, le dict de classe est enveloppé par un proxy qui empêche la modification directe, de sorte que la déclaration est fausse des objets en général.Vous êtes techniquement correct... le meilleur type de correct. Je vais cop pour simplifier à l'extrême pour l'amour d'un débutant.
J'ai pensé que c'est ce que l'on fait, car je suis sûr que vous connaissez Python très bien. Je suis juste TOC assez à penser qu'il a besoin de la note de bas de page.
OriginalL'auteur kindall
Cette réponse ne concerne que les nouveaux style de classes Python, qui sous-classe
object
. Nouvelles catégories ont été ajoutées à la section 2.2, et ils sont le seul type de classe disponibles dans PY3.La classe elle-même est une instance d'une métaclasse, qui est généralement
type
:Ci-dessus docstring, vous pouvez créer une instance de la métaclasse directement pour créer une classe:
L'appel d'une classe est gérée par la métaclasse
__call__
méthode, par exempletype.__call__
. Ce à son tour appelle la classe__new__
constructeur (généralement héritées) avec les arguments d'appel dans le but de créer une instance. Ensuite, il appelle__init__
, qui peut définir des attributs d'instance.La plupart des objets ont une
__dict__
qui permet de configurer et de supprimer des attributs de façon dynamique, commeself.value = 10
oudel self.value
. Il est généralement mauvaise forme pour modifier un objet__dict__
directement, et en fait rejeté pour une classe (c'est à dire une classe dict est enveloppé de désactiver la modification directe). Si vous avez besoin d'accéder à un attribut de façon dynamique, l'utilisation de la les fonctions intégréesgetattr
,setattr
, etdelattr
.Le modèle de données définit les méthodes spéciales personnalisation de l'attribut d'accès:
__getattribute__
,__getattr__
,__setattr__
, et__delattr__
. Une classe peut également définir le descripteur de protocole méthodes__get__
,__set__
, et__delete__
pour déterminer comment ses instances se comportent comme des attributs. Reportez-vous à la descripteur de guide.Lors de la recherche d'un attribut,
object.__getattribute__
recherche tout d'abord la classe de l'objet et les classes de base à l'aide de la C3 méthode de résolution de l'ordre de la classe:Noter qu'un descripteur de données défini dans la classe (par exemple, un
property
ou unmember
pour une machine à sous) l'emporte sur l'instance dict. D'autre part, un non-descripteur de données (par exemple, une fonction) ou un non-descripteur attribut de classe peut être assombri par une instance de l'attribut. Par exemple:Utilisation
super
à l'attribut proxy d'accès de la classe suivante dans la méthode de résolution de l'ordre. Par exemple:OriginalL'auteur eryksun