SICP_Python版:Chapter 2:Implement simple object system

本文介绍了一种使用Python闭包来保存状态并构建简单对象系统的方法,这有助于理解Python对象系统的实现原理。通过具体实例展示了如何利用闭包实现类和实例的构造。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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'))

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值