2015-10-23 14 views
5

ho classe in Python come questolambda statiche in pitone

import numpy as np 
class BackPropogationNetwork: 
     # Static lambdas 
     sigmoid = lambda x : 1/(1+np.exp(-x)) 
     sigmoid_prime = lambda sigmoid: sigmoid(1-sigmoid) 

e questo è il contructor

def __init__(self): 
    self.some_attr = self.sigmoid(2) 

ottengo questo errore

TypeError: <lambda>() takes exactly 1 argument (2 given) 

Se chiamo come questo

self.some_attr = ClassName.sigmoid() 

ottengo questo errore

TypeError: unbound method <lambda>() must be called with BackPropogationNetwork instance as first argument (got int instance instead) 
+1

Se si definiscono i 'lambda's all'interno della definizione di classe, sono lo stesso di qualsiasi altro metodo di istanza - è necessario l'argomento' self', e non li può chiamare sulla classe. Perché stai usando 'lambda' comunque? Se vuoi un '@ classmethod', scrivine uno. – jonrsharpe

+0

Che dire di 'ClassName.sigmoid (2)'? –

+0

usa invece 'def'. 'lambda' in python è una funzionalità rotta e non fornisce una potenza extra come in altre lingue. quindi utilizzare il descrittore '@ staticmethod'. 'self' implica che il sé sia ​​anche un parametro. quindi stai passando due parametri. – HuStmpHrrr

risposta

4

È necessario avvolgere le lambda in staticmethod objects:

class BackPropogationNetwork: 
    sigmoid = staticmethod(lambda x : 1/(1+np.exp(-x))) 
    sigmoid_prime = staticmethod(lambda sigmoid: sigmoid(1-sigmoid)) 

lambda espressioni continuano a produrre oggetti funzione, solo utilizzando la sintassi diversa (limitato). Le stesse regole si applicano come definizione di funzioni in una classe; se vuoi che sia un metodo statico, devi comunque avvolgerli.

+0

Cosa significa nel mio codice? –

+0

penso che 'staticmethod' sarebbe più appropriato – Javier

+0

@Goutam non è chiaro cosa stai chiedendo – jonrsharpe

2

Così la vostra funzione sigmoide è kinda indipendente della classe, avrebbe senso per tenerlo fuori, a meno che:

  • si desidera non inquinare il namespace del modulo
  • si vuole aumentare la rilevabilità della funzione
  • si desidera sovrascrivere questo metodo. Supponiamo che tu abbia deciso e nulla possa cambiarlo, beh in tal caso puoi farlo. Quando chiami un metodo come self.method() python passa il primo argomento al funtion dell'istanza, così puoi renderti lambda come questo: sigmoid = lambda self, x : 1/(1+np.exp(-x)) oppure puoi fare quello che altri hanno suggerito come renderlo un metodo statico, poiché staticmethod è un decoratore, (funzione che prende una funzione) può essere chiamato in questo modo

    In [1]: class A: 
        ...:  s = staticmethod(lambda x: x) 
        ...:  def a(self): 
        ...:   print self.s(10) 
        ...: 
    
    In [2]: f = A() 
    
    In [3]: f.a() 
    10 
    
0

I suoi due sigma di non sono metodi di classe. Ciò significa che quando li chiami si aspettano che la classe sia il primo argomento implicito.

Questo errore

TypeError: <lambda>() takes exactly 1 argument (2 given) 

si verifica su questa chiamata

self.some_attr = self.sigmoid(2) 

perché oggetto istanza di classe viene passato implicitamente con l'int 2. Ma la tua sigma è definito per accettare un solo argomento.

E non credo che si ottiene questo errore

TypeError: unbound method <lambda>() must be called with BackPropogationNetwork instance as first argument (got int instance instead) 

con questa chiamata

self.some_attr = ClassName.sigmoid() 

L'errore si dovrebbe ottenere dovrebbe essere qualcosa di simile.

TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'type' 

Potrebbe essere stato commesso un errore di copia durante la digitazione della domanda.