问题描述
我试图理解python类系统实现中的初始化功能,该功能摘自本书(SICP 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
'. Usingget
, if the attribute is not in object, it is looked up in class definition and abind_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 usesinit_instance(cls, *args)
to create a new object instance with arbitrary number of arguments (for methods of the attributes).cls
argument forinit_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 withinstance = make_instance(cls)
, the instance inherits features of the class throughcls
dictionary.init = cls['get']('__init__')
,init
is created, a statement that looks up if__init__
keyword was passed in attributes tomake_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 函数可以引用.
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!