En Javascript, puedo hacer esto:

var person = {
  name: 'Joe',
  age:  '35',
  speak: function(){
    return 'o hai i am joe'
  }
}

Entonces puedo llamar a ese método:

person.speak()
'o hai i am joe'

Sé que esto se puede hacer con las clases en Python, y presumiblemente ese es el camino correcto.

No obstante, tengo curiosidad: ¿hay alguna forma de agregar una función como valor en un diccionario de Python?

1
user18015 28 jul. 2011 a las 01:27

4 respuestas

La mejor respuesta
person = {
  'name': 'Joe',
  'age':  '35',
  'speak': lambda: 'o hai i am joe',
}

Sin embargo, en Python (a diferencia de JavaScript), el atributo y el acceso [] son diferentes. Para ejecutar hablar, escribir

person['speak']()
5
phihag 27 jul. 2011 a las 21:55

Una de las diferencias clave entre javascript y python es el manejo del objeto de destino en el espacio de nombres del método. En javascript, this se establece según sea necesario cuando el método se llama , pero en Python, self se determina en una combinación de tiempo de creación de clase (convirtiendo funciones en métodos de instancia) y cuando se accede al atributo (enlazando la propiedad im_self en el método de instancia). Incluso si usara solo el acceso a atributos, superar esta diferencia es un poco complicado cuando desea vincular métodos de instancia a instancias individuales, en lugar de la clase.

import functools
class JSObject(object):
    def __getattribute__(self, attr):
        """
        if the attribute is on the instance, and the target of that is
        callable, bind it to self, otherwise defer to the default getattr.
        """
        self_dict = object.__getattribute__(self, '__dict__')
        if attr in self_dict and callable(self_dict[attr]):
            return functools.partial(self_dict[attr], self)
        else:
            return object.__getattribute__(self, attr)

Aquí está en acción:

>>> foo = JSObject()
>>> foo.bar = 'baz'
>>> foo.bar
'baz'
>>> foo.quux = lambda self: self.bar
>>> foo.quux
<functools.partial object at 0x7f8bae264ba8>
>>> foo.quux()
'baz'

Hacer que la clase anterior sea un poco más dict como un tema separado, y en mi opinión, no es la mejor "característica" de JavaScript para emular, pero suponiendo que quisiéramos eso "de todos modos", probablemente comenzaríamos subclasificando { {X1}}, y una vez más sobrecargando __getattr__ o __getattribute__, que dejaré como ejercicio.

2
SingleNegationElimination 27 jul. 2011 a las 21:43

Puede, ya sea definiendo las funciones con anticipación:

def speak_function(txt):
  print txt

person = {
  'speak': speak_function
}

O posiblemente usando lambdas (en el caso de retornos simples):

person = {
  'speak': lambda x: x
}
0
g.d.d.c 27 jul. 2011 a las 21:30
def test():
    print "hello"

testDict = {"name" : "Joe", "age" : 35, "speak" : test}

testDict["speak"]()
2
rzetterberg 27 jul. 2011 a las 21:30