您的位置:首页 > 移动开发 > Objective-C

SICP_Python版:Chapter 2:Implement simple object system

2016-08-27 20:32 459 查看

SICP介绍了如何利用简单的闭包来保存状态,从而来构造一个简单的object系统,加深对python object system实现的理解.

(1)实现类的构造:

很容易理解这个代码:首先看参数是一个dictionary,里面存储着一个类的各个属性(property,method).我们将这个attributes作为参数保存起来,然后创建一改局部的dict里面有两个key_value,分别用来查找和修改类的成员。至于base_cls很显然是递归定义的。

def make_class(attributes, base_cls=None):
def get(name):
if name in attributes:
return attributes[name]
if base_cls:
return base_cls['get'](name)

def set_value(name, value):
attributes[name] = value

def new(*args):
return init_instance(cls, *args)
cls = {'get': get, 'set': set_value, 'new': new}
return cls


(2):实现instance的构造

这里相对复杂一点,首先instance利用类作为参数这个显然,然后我们需要将另一个闭包外部的变量instance建立起来,并且加入get和set成员。对于任何一改成员的引用,首先需要判断这个成员是否在instance的属性里面,如果在就直接返回。否则需要查询是否在类里面,如果在,则需要判断这个成员是否可callable。如果是,那么不能直接返回相应的类方法,而是要想办法将self参数传入到方法里面。这样解决的办法是再构造一个闭包并且返回函数,把instance这个参数利用闭包保存起来。然后返回一改函数。在下面的代码里面,将这些逻辑处理交给函数bind_method处理,它将函数method绑定到变量instance上。

最后是初始化的过程,这个就比较简单了,首先获取对应类的init函数,如该存在,那么就对instance进行初始化,传入相关参数即可。

def make_instance(cls):
def get_value(name):
if name in attributes:
return attributes[name]
else:
value = cls['get'](name)
return bind_method(value, instance)

def set_value(name, value):
attributes[name] = value
attributes = {}
instance = {'get': get_value, 'set': set_value}
return instance

def bind_method(value, instance):
if callable(value):
def method(*args):
return value(instance, *args)
return method
else:
return value

def init_instance(cls, *args):
instance = make_instance(cls)
init = cls['get']('__init__')
if init:
init(instance, *args)
return instance


(3):给出一例子:

def make_accound_cls():
def __init__(self, account_holder, balance):
self['set']('holder', account_holder)
self['set']('balance', balance)

def withdraw(self, amount):
balance = self['get']('balance')
if balance < amount:
return 'insufficient balance'
self['set']('balance', balance - amount)
return self['get']('balance')

attributes = {'__init__': __init__, 'withdraw': withdraw}
return make_class(attributes)
Account = make_accound_cls()
jam_account = Account['new']('jam', 100)
jam_account['get']('withdraw')(30)
print(jam_account['get']('balance'), jam_account['get']('holder'))


总结:通过闭包来保存相应的状态是构建的核心。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: