类实例实现,初始化实例-来自SICP python

类实例实现,初始化实例-来自SICP python,python,python-3.x,python-2.7,class,sicp,Python,Python 3.x,Python 2.7,Class,Sicp,我试图理解python类系统实现中的初始化函数,这些函数取自本书 init_instance(初始化)函数“返回类型为cls、使用args初始化的新对象。”就是我遇到问题的地方。下面我试图通过解释我所理解的内容来缩小我的问题范围 def make_instance (cls): #good with this """return a new object instance, which is a dispatch dictionary""" def get_value(name)

我试图理解python类系统实现中的初始化函数,这些函数取自本书

init_instance
(初始化)函数
“返回类型为cls、使用args初始化的新对象。”
就是我遇到问题的地方。下面我试图通过解释我所理解的内容来缩小我的问题范围

def make_instance (cls): #good with this
    """return a new object instance, which is a dispatch dictionary"""
    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): #good with this
    """Return a bound method if value is callable, or value otherwise"""
    if callable (value):
        def method(*args):
            return value (instance, *args)
        return method
    else:
        return value

def make_class (attributes, base_class = None): 
    """Return a new class, which is a dispatch dictionary."""
    def get_value(name):
        if name in attributes:
            return attributes[name]
        elif base_class is not None:
            return base_class['get'](name)
    def set_value(name,value):
        attributes[name] = value
    def new(*args):
        return init_instance(cls, *args)
    cls = {'get':get_value,'set':set_value,'new':new}
    return cls

def init_instance(cls,*args): #problem here
    """Return a new object with type cls, initialized with args"""
    instance = make_instance (cls)
    init = cls ['get'] ('__init__')
    if init:                            
        init (instance, *args)          #No return function here
    return instance
下面是对上述函数的调用,以创建一个名为“Jim”的新类对象

def make_my_class():    #define a custom class
    pass
    return make_class({'__init__':__init__})   #return function that implements class

my_class = make_my_class()  #create a class
my_class_instance = my_class['new'] ('Jim') #create a class instance with ['new']
我的理解 由于这是类的函数实现,因此与内置python类进行比较。下面我所说的Python类/对象/实例,都是指内置的

  • make_instande(cls)
    :接受'class'->
    cls
    参数(消息fxn字典本身)并描述对象的行为,即提供所需的属性以类似于python对象的方式进行行为。我们可以使用“
    set
    ”设置属性,这些属性保持在属性字典的本地。使用
    get
    ,如果属性不在对象中,则在类定义中查找该属性,并调用
    bind_方法
    函数
  • bind_method(value,instance)
    :将类定义中的函数绑定到对象实例,以模拟python类实例中的python方法。若值不可调用,则返回值(父类的python属性)
  • make_class(attributes,base_class=None)
    :设置类的行为,并能够从另一个类继承。以类似的方式使用get和set to生成_实例,只是它不需要bind_方法。它使用
    init_instance(cls,*args)
    创建具有任意数量参数的新对象实例(用于属性的方法)<
    init_实例的code>cls
    参数将类分派字典传递给对象实例。因此,对象“继承”(因为没有更好的词)类特性
  • init_实例(cls,*args)
    :这里我有点不确定。首先,函数使用
    instance=make_instance(cls)
    创建一个实例,实例通过
    cls
    字典继承类的特征
    init=cls['get']('uuuuu init'uuuu')
    init
    ,创建一条语句,用于查找是否在属性中将
    \uuuu init\uuuuu
    关键字传递给
    生成类
    如果init:init(实例,*args)
    使args成为实例的本地参数?返回一个实例
我可以把我的问题缩小到-
init\u实例
返回到
make\u类
中的
new(*args)
。这意味着实例字典将返回到
new(*args)
。但是,
make_class
返回
cls
,这意味着我们必须以某种方式更新
cls
以包含
实例
属性。这是怎么做到的?很可能是这条语句
init(instance,*args)
,但我不知道如何分解这条语句。我没有看到
init
作为fn,参数是如何传递给它的

这段代码有点棘手,因此您发现其中一些代码令人费解也就不足为奇了。要理解它,你需要理解。中有一些关于Python中闭包的信息

init\u instance
使用
instance=make\u instance(cls)
创建一个新实例,然后它查找
cls
init
方法,如果它存在,它用新实例和
args
中传递的任何内容调用该
init
方法。无论是
make_instance
还是
init_instance
都不要修改
cls
字典,或者在创建
cls
时传递给
make_class
属性字典。实际情况是,
make\u instance
的每次调用都会为它创建的实例创建一个新的
属性
dict,实例dict中的
get
set
函数可以引用该dict

你的
make\u my\u class
定义没有多大意义。它有一个冗余的
pass
语句,并且
make_类({''''uu___________}):{uu_____})将不起作用,因为您没有在任何地方定义
\uu____
,它需要一个初始化类实例的函数

这是您的代码的修改版本。我为
我的类
创建了一个简单的
初始化
函数,并添加了几个
打印
调用,这样我们就可以了解代码的作用

def hexid(obj):
    return hex(id(obj))

def make_instance(cls): # good with this
    """ Return a new object instance, which is a dispatch dictionary """
    def get_value(name):
        print('INSTANCE GET_VALUE', name, 'from', hexid(attributes))
        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 = {'test': 'Default Test'}
    print('Created instance attributes', hexid(attributes))
    instance = {'get': get_value, 'set': set_value}
    return instance

def bind_method(value, instance): # good with this
    """ Return a bound method if value is callable, or value otherwise """
    if callable(value):
        def method(*args):
            return value(instance, *args)
        return method
    else:
        return value

def make_class(attributes, base_class=None): 
    """ Return a new class, which is a dispatch dictionary. """
    def get_value(name):
        print('\nCLASS GET_VALUE', name, 'from', hexid(attributes))
        if name in attributes:
            return attributes[name]
        elif base_class is not None:
            return base_class['get'](name)

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

    def new(*args):
        return init_instance(cls, *args)

    print('Creating class with attributes', hexid(attributes))
    cls = {'get': get_value, 'set': set_value, 'new': new}
    return cls

def init_instance(cls, *args): # problem here
    """ Return a new object with type cls, initialized with args """
    instance = make_instance(cls)
    init = cls['get']('__init__')
    if init:
        print('Calling init of', hexid(cls), 'on', hexid(instance), 'with', args)
        init(instance, *args)          #No return here
    return instance

def make_my_class(): # define a custom class
    # Create a simple __init__ for the class
    def __init__(inst, *args):
        print('INIT', hexid(inst), args)
        inst['set']('data', args)

    # return a dict that implements class
    return make_class({'__init__': __init__})

# test

#create a class
my_class = make_my_class()

#create some class instances
jim = my_class['new']('Jim')
jim['set']('test', 'Hello')

fred = my_class['new']('Fred') 

print('CLASS', hexid(my_class))
print('\nINSTANCE', hexid(jim))
print(jim['get']('data'))
print(jim['get']('test'))

print('\nINSTANCE', hexid(fred))
print(fred['get']('data'))
print(fred['get']('test'))
输出

Creating class with attributes 0xb71e67d4
Created instance attributes 0xb71373ec

CLASS GET_VALUE __init__ from 0xb71e67d4
Calling init of 0xb7137414 on 0xb71373c4 with ('Jim',)
INIT 0xb71373c4 ('Jim',)
Created instance attributes 0xb7137374

CLASS GET_VALUE __init__ from 0xb71e67d4
Calling init of 0xb7137414 on 0xb713734c with ('Fred',)
INIT 0xb713734c ('Fred',)
CLASS 0xb7137414

INSTANCE 0xb71373c4
INSTANCE GET_VALUE data from 0xb71373ec
('Jim',)
INSTANCE GET_VALUE test from 0xb71373ec
Hello

INSTANCE 0xb713734c
INSTANCE GET_VALUE data from 0xb7137374
('Fred',)
INSTANCE GET_VALUE test from 0xb7137374
Default Test

这很有帮助。参考资料也很好。我不知道自由变量。我将使用print()和local()以及本答案中提到的其他技术。