python: rileva se il mio metodo viene chiamato con 0 o 1 arg

2

Voglio scrivere una suite di metodi che fungono da getter quando passano zero argomenti e come setter quando passano un singolo argomento. Ho due due implementazioni ragionevoli, mostrate di seguito. Uno è migliore dell'altro, o forse esiste ancora un modo migliore?

class Thing(object):

    def __init__(self):
        self._size = 0

    def sizeA(self, *args):
        if not args:
            return self._size
        self._size = args[0]
        return self

    UNIQUE_ID = []

    def sizeB(self, arg=UNIQUE_ID):
        if arg is self.UNIQUE_ID:
            return self._size
        self._size = arg
        return self

Un paio di commenti:

sizeA() benchmark più veloce di sizeB() , ma non mi dà il controllo del conteggio degli argomenti. sizeB() funziona, ma dipende da UNIQUE_ID che è invariante, e mi chiedo se ci sono circostanze (ad es. pickling) che potrebbero causarne l'interruzione.

P.S .: Anche se attualmente sto sviluppando in python-2.7, sono aperto a specifiche risposte python-3.x come appropriato.

    
posta fearless_fool 28.04.2016 - 01:26
fonte

1 risposta

1

Una sentinella e un argomento di default sono un buon modo per farlo. Però userei un oggetto arbitrario, non una lista (preferenza, e in questo modo qualcuno non se ne andrà a giocherellare con esso).

class A(object):
    _DEFAULT = object()

    def __init__(self):
        self._size = 0

    def sizeC(self, arg=_DEFAULT):
        if arg is not DEFAULT:
            self._size = arg
        return self._size

E pickle gestirà bene (lo gestisce anche bene con un elenco, cambia _DEAFULT in [] e lo cambia in print id(y._DEFAULT) ).

a = A()
a.sizeC(10)

x = pickle.dumps(a)
y = pickle.loads(x)

print y._DEFAULT
print y.sizeC()
print y.sizeC(20)
print y.sizeC()
print y._DEFAULT
print a._DEFAULT

andy@batman:~$ p tmp.py 
<object object at 0x7ff952223090>
10
20
20
<object object at 0x7ff952223090>
<object object at 0x7ff952223090>

Non riesco a pensare a una situazione in cui ciò potrebbe causare problemi, ed è un modello accettato per quanto ne so (non ho citazioni a portata di mano).

Per curiosità, qual è la differenza nel benchmark tra le due opzioni?

    
risposta data 07.07.2016 - 15:18
fonte

Leggi altre domande sui tag