È un modello comune in Python avere le variabili di istanza assegnate in un costruttore che iniziano con un trattino basso?

1

Recentemente ho iniziato a utilizzare UtilSnips , un plugin Vim che consente un certo livello di automazione durante la codifica utilizzando frammenti di codice tipo template per i frammenti di codice comuni (definizioni di classi e funzioni, ad esempio).

Quando utilizzo un popolare pacchetto snippet con Python, ho notato che gli snippet utilizzati durante la scrittura di una classe utilizzano un modello I ' non ho mai visto prima in __init__ quando si usano più argomenti di appena self :

class MyClass(object):

    """Docstring for MyClass. """

    def __init__(self, user, password):
        """TODO: to be defined.

        :user: TODO
        :password: TODO

        """
        self._user = user  # this is the pattern I'm unfamiliar with
        self._password = password

È pratica comune (o buona) usare il trattino basso quando si assegna variabili di istanza in un costruttore per una classe in Python, o è probabile che sia solo la preferenza dell'autore del snippet pack? Non ho visto questo tipo di convenzione di denominazione in nessun altro codice Python con cui ho interagito.

    
posta Jules 11.02.2016 - 15:49
fonte

1 risposta

2

Principali sottolineature

Un carattere di sottolineatura iniziale significa "mani libere" per l'utente, sebbene un utente avanzato possa aspettarsi di usarlo in determinate circostanze, ad esempio quando sottoclassi il tuo oggetto.

Dimostrazione di utilizzo con decoratore di proprietà

Tendiamo a utilizzare caratteri di sottolineatura quando si utilizza una proprietà, ad esempio:

class MyClass(object):
    def __init__(self, user, password):
        self._user = user
        self._password = password
    @property
    def user(self):
        return self._user
    # The rest are optional - leaving off has same behavior
    # but this demonstrates usage.
    @user.setter
    def user(self, value):
        """optional, raise a custom AttributeError message"""
        raise AttributeError('do not attempt to modify user member')
    @user.deleter
    def user(self):
        """optional, raise a custom AttributeError message"""
        raise AttributeError('do not attempt to modify user member')

Quindi, usando il tuo codice puoi creare l'oggetto, ma quando si tenta di modificare l'attributo ricevono un avvertimento dicendo loro le mani, per le quali hai apparentemente una buona ragione:

>>> mc = MyClass('foo', 'bar')
>>> mc.user = 'huh?'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in user
AttributeError: do not attempt to modify user member
>>> del mc.user
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in user
AttributeError: do not attempt to modify user member

Senza i nostri metodi setter e deleter opzionali otteniamo un messaggio di errore più generico:

>>> mc.user = 'huh?'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> del mc.user
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't delete attribute
    
risposta data 13.02.2016 - 03:18
fonte

Leggi altre domande sui tag