Python中javascript风格的对象方法

Javascript-style object methods in Python?

本文关键字:对象 方法 风格 javascript Python      更新时间:2023-09-26

在Javascript中我可以这样做:

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

然后我可以调用那个方法:

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

我知道这可以用Python中的类来完成,而且这大概是正确的方法。

尽管如此,我还是很好奇——有没有办法在Python字典中添加一个函数作为值?

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

然而,在Python中(与JavaScript不同),attribute和[]访问是不同的。要执行speak,写入

person['speak']()

javascript和python之间的关键区别之一是在方法的命名空间中处理目标对象。在javascript中,当方法是调用时,this是根据需要设置的,但在python中,self是在类创建时间(将函数转换为instancemethod)和访问属性(在instancemethod上绑定im_self属性)的组合中确定的。即使您只使用属性访问,当您希望将实例方法绑定到单个实例而不是类时,克服这种差异也有点棘手。

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)

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

使上述类更像dict是一个单独的问题,在我看来,不是JavaScript模仿的最佳"功能",但假设我们想要"无论如何",我们可能会从子类化dict开始,并再次重载__getattr____getattribute__,我将离开作为练习。

def test():
    print "hello"
testDict = {"name" : "Joe", "age" : 35, "speak" : test}
testDict["speak"]()

您可以通过提前定义函数:

def speak_function(txt):
  print txt
person = {
  'speak': speak_function
}

或者可能使用lambdas(在简单返回的情况下):

person = {
  'speak': lambda x: x
}