类实例的实现,初始化实例-来自SICP python [英] Class instance implementation, initializing instance - from SICP python

查看:52
本文介绍了类实例的实现,初始化实例-来自SICP python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解python类系统实现中的初始化功能,该功能摘自本书

I'm trying to the understand the initialization function in a python class system implementation, taken from this book (SICP python - reference to book section).

init_instance (初始化)函数"返回一个类型为cls,用args初始化的新对象."" 是我遇到麻烦的地方.下面,我试图通过解释我的理解来缩小问题范围.

The init_instance (initialization) function """Return a new object with type cls, initialized with args.""" is where I'm having trouble. Below I've tried to narrow down my question, by explaining what I've understood.

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"的新类对象

Here is a call to above functions, to create a new class object called '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 Class/object/instance下方,我的意思是内置的.

What I understand

Since this is an functional implementation of classes, the comparison is with inbuilt python classes. Below wherever I say Python Class/object/instance, I mean inbuilt.

  • make_instande(cls):采用'class'-> cls 参数(消息fxn字典本身)并描述对象的行为,即提供所需的属性表现得与python对象类似.我们可以使用' set '设置属性,这些属性在属性字典中保持局部状态.使用 get ,如果属性不在对象中,则在类定义中查找该属性,然后调用 bind_method 函数.
  • bind_method(value,instance):将类定义中的函数绑定到对象实例,以在python类实例中模拟python方法.如果value是不可调用的,则返回value(父类的python属性).
  • make_class(属性,base_class =无):设置类的行为,并具有从另一个类继承的能力.使用get和set to与make_instance相似,不同之处在于,它不需要bind_method.它使用 init_instance(cls,* args)创建一个具有任意数量参数(用于属性方法)的新对象实例. init_instance cls 参数将类调度字典传递给对象实例.因此,对象继承"(由于缺少更好的词)是类的特征.
  • init_instance(cls,* args):在这里我不确定.首先,该函数使用 instance = make_instance(cls)创建一个实例,该实例通过 cls 字典继承类的特征. init = cls ['get']('__ init __'),创建 init ,如果传入 __ init __ 关键字,则会查找一条语句属性,如果初始化:init(instance,* args)是否使args在实例本地化?返回一个实例.
  • make_instande(cls) : takes the 'class' -> cls argument (a message fxn dictionary itself) and describes the behaviour of an object , i.e. provides required properties to behave in a similar way to a python object. We can set attributes, that stay local to attributes dictionary using 'set'. Using get, if the attribute is not in object, it is looked up in class definition and a bind_method function is called.
  • bind_method(value,instance): binds a function in class definition to the object instance to emulate python methods in a python class instance. if value is not callable, returns value (python attribute from parent class).
  • make_class (attributes, base_class = None): Sets the behaviour of a class, with ability to inherit from another class. Uses get and set to in a similar fashion to make_instance, except, it doesn't require a bind_method. It uses init_instance(cls, *args) to create a new object instance with arbitrary number of arguments (for methods of the attributes). cls argument for init_instance passes class dispatch dictionary to the object instance. Hence, the object 'inherits' (for lack of a better word) the class features.
  • init_instance(cls, *args): Here I am a little unsure. Firstly, the function makes an instance with instance = make_instance(cls), the instance inherits features of the class through cls dictionary. init = cls['get']('__init__') , init is created, a statement that looks up if __init__ keyword was passed in attributes to make_class, , if init: init(instance, *args) makes args local to the instance? Returns an instance.

init_instance make_class 中的 new(* args)的返回.这意味着实例字典将返回到 new(* args).但是, make_class 返回 cls ,这意味着我们必须以某种方式更新 cls 以包含 instance 属性.那是怎么做的?该语句最有可能是 init(实例,* args),但我不知道该如何分解该语句.我还没有将 init 视为fn,如何将参数传递给它?

init_instance is a return to new(*args) in make_class. Which means an instance dictionary is returned to new(*args). However, make_class returns cls which means we have to update cls somehow to contain instance properties. How is that that being done? It's most likely this statement init (instance, *args) but I don't know how to break down this statement. I haven't seen init as fn, how are arguments being passed to it?

推荐答案

此代码有些棘手,因此发现其中一些令人困惑也就不足为奇了.要了解它,您需要了解关闭.在此答案中有一些有关Python闭包的信息.

This code is a little tricky, so it's not surprising that you find some of it puzzling. To understand it, you need to understand closures. There's some info about closures in Python in this answer.

init_instance 使用 instance = make_instance(cls)创建一个新实例,然后查找 cls ,如果存在,它将使用新实例以及在 args 中传递的内容调用该 init 方法. make_instance init_instance 都不会修改 cls 字典或传递给 make_class <的 attributes 字典./code>创建 cls 时.实际发生的情况是,每次调用 make_instance 都会为其创建的实例创建一个新的 attributes 字典,该 get set <实例字典中的/code>函数可以引用.

init_instance creates a new instance with instance = make_instance(cls), then it looks up the init method of cls, and if it exists, it calls that init method with the new instance and whatever was passed in args. Neither make_instance nor init_instance modify the cls dictionary, or the attributes dictionary that was passed to make_class when cls was created. What actually happens is that each call of make_instance creates a new attributes dict for the instance it creates, which the get and set functions in the instance dict can reference.

您的 make_my_class 定义没有多大意义.它有一个多余的 pass 语句,并且 make_class({'__ init__':__init __})将不起作用,因为您尚未定义 __ init __ 在任何地方,都需要一个函数来初始化您的类实例.

Your make_my_class definition doesn't make much sense. It has a redundant pass statement, and make_class({'__init__': __init__}) won't work because you haven't defined __init__ anywhere, that needs to be a function which will initialize your class instances.

这是您代码的修改版本.我为 my_class 创建了一个简单的 __ init __ 函数,并添加了几个 print 调用,以便我们了解代码的功能.

Here's a modified version of your code. I've created a simple __init__ function for my_class, and added several print calls so we can get an idea of what the code's doing.

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

这篇关于类实例的实现,初始化实例-来自SICP python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆