Python中的原型编程

And*_*rea 9 javascript python inheritance prototype prototypal-inheritance

Javascript为其对象使用基于原型的模型.尽管如此,该语言非常灵活,并且很容易用几行函数编写,这些函数替换了构造上的其他类型.例如,可以创建一个class函数,模拟标准类行为,包括继承或私有成员.或者可以通过编写一个curry函数来模仿功能工具,例如,一个函数将获取一个函数及其一些参数并返回部分应用的函数.

我想知道是否可以反过来模仿更古典语言中的原型方法.特别是我一直在思考是否有可能在Python中模仿原型,但缺乏对匿名函数的支持(比lambdas更常见)让我陷入困境.

是否有可能编写一些函数来模仿基于类的语言中的指标,特别是在Python中?

编辑让我举一个例子,说明如何实现这样的事情(但我真的无法做到这一切).

首先,最接近Javascript对象的东西是Python字典.所以我们可以有简单的对象

foo = {
    'bar': 1,
    'foobar': 2
}
Run Code Online (Sandbox Code Playgroud)

当然我们想要添加方法,只要该方法适合lambda,这就不是问题

foo = {
    'bar': 1,
    'foobar': 2,
    'method': lambda x: x**2
}
Run Code Online (Sandbox Code Playgroud)

所以现在我们可以打电话了

foo['method'](2)
>>> 4
Run Code Online (Sandbox Code Playgroud)

现在,如果我们有任意函数作为方法,我们就可以继续这样做.首先,我们需要内部的功能foo才能访问foo自己; 否则它们只是普通的功能,而不是方法.

我想可以通过应用一个makeObject函数来实现这一点,该函数foo循环遍历foo值,并且每当找到可调用的值时,修改其__call__属性以foo作为其第一个参数传递.

在这个阶段,我们将拥有自立对象,可以在不需要创建类的情况下声明它们.

然后我们需要能够给出foo一个原型,它可以作为makeObject函数的第二个参数传递.该函数应该修改foo.__getattr__foo.__setattr__如下:每当找不到属性时foo,应该搜索它foo.prototype.

因此,我认为我能够实现这一点,期待一件事:我想不出任何方法来声明方法比lambdas更复杂,除了事先声明它们并将它们附加到我的对象.问题是缺乏匿名功能.我在这里问,因为也许一些Python大师可以找到一些聪明的方法来规避这个.

Len*_*bro 7

它在Python中比在JS中容易得多.您的JS代码可以在Python中替换为:

>>> class Foo(object):
...      pass

>>> foo = Foo()
>>> foo.bar = 1
>>> foo.foobar = 2
Run Code Online (Sandbox Code Playgroud)

然后您也可以动态添加方法

>>> foo.method = lambda x: x**2
>>> foo.method(2)
4
Run Code Online (Sandbox Code Playgroud)

对于比lambdas更复杂的方法,你将它们声明为函数,并且它们可以访问foo本身,没有问题:

>>> def mymethod(self, bar, foobar):
...     self.bar = bar
...     self.foobar = foobar
>>> foo.mymethod = mymethod
>>> foo.mymethod(1,2)
>>> foo.bar
1
>>> foo.foobar
2
Run Code Online (Sandbox Code Playgroud)

或者就此而言:

>>> mymethod(foo, 3, 4)
>>> foo.bar
3
>>> foo.foobar
4
Run Code Online (Sandbox Code Playgroud)

一样.

正如您所看到的,在Python中执行您的示例几乎是非常简单的.问题是为什么.:)我的意思是,这会更好:

>>> class Foo(object):
...     def __init__(self, bar, foobar):
...         self.bar = bar
...         self.foobar = foobar
...     def method(self, x):
...         return x**2
Run Code Online (Sandbox Code Playgroud)

  • 我认为这还不够 - 有一个属性解析顺序可以在原型层次结构中运行.另一件事 - 我不确定Javascript是否隐式绑定了对象内部状态的操作方法.如果确实如此,那么动态添加方法需要更多魔法. (6认同)

One*_*One 2

简短版本,是的,但它比JS.

来自Python 中的元类编程

>>> class ChattyType(type):
...     def __new__(cls, name, bases, dct):
...         print "Allocating memory for class", name
...         return type.__new__(cls, name, bases, dct)
...     def __init__(cls, name, bases, dct):
...         print "Init'ing (configuring) class", name
...         super(ChattyType, cls).__init__(name, bases, dct)
...
>>> X = ChattyType('X',(),{'foo':lambda self:'foo'})
Allocating memory for class X
Init'ing (configuring) class X
>>> X, X().foo()
(<class '__main__.X'>, 'foo')
Run Code Online (Sandbox Code Playgroud)

另请检查什么是 Python 中的元类

编辑:检查基于原型的 OO,这是您将得到的最接近的东西,但它总是会归结为使用 lambda 或只是在外部定义函数并将指向它的指针添加到类对象。