我试图理解 python 类系统实现中的初始化函数,取自这本书 (SICP python - reference to book section) .
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)
:采用“类”->cls
参数(消息 fxn 字典本身)并描述对象的行为,即提供所需的属性以类似于 python 对象的方式运行。我们可以使用“set
”设置属性,这些属性保留在属性字典中。使用get
,如果属性不在对象中,则在类定义中查找它并调用bind_method
函数。bind_method(value,instance)
:将类定义中的函数绑定(bind)到对象实例,以在 python 类实例中模拟 python 方法。如果值不可调用,则返回值(来自父类的 python 属性)。make_class (attributes, base_class = None)
:设置一个类的行为,具有从另一个类继承的能力。以与 make_instance 类似的方式使用 get 和 set to,不同之处在于它不需要 bind_method。它使用init_instance(cls, *args)
创建一个具有任意数量参数(用于属性方法)的新对象实例。init_instance
的cls
参数将类调度字典传递给对象实例。因此,对象“继承”(缺少更好的词)类特征。init_instance(cls, *args)
:这里我有点不确定。首先,该函数使用instance = make_instance(cls)
创建一个实例,该实例通过cls
字典继承类的特性。init = cls['get']('__init__')
,init
被创建,一个查询是否传入了__init__
关键字的语句make_class
的属性, ,if init: init(instance, *args)
使 args 成为实例的本地参数?返回一个实例。
我可以将我的问题缩小到 -
init_instance
是make_class
中new(*args)
的返回。这意味着实例字典返回给 new(*args)
。但是,make_class
返回 cls
,这意味着我们必须以某种方式更新 cls
以包含 instance
属性。那是怎么做到的?很可能是这条语句 init (instance, *args)
但我不知道如何分解这条语句。我还没有看到 init
是 fn,参数是如何传递给它的?
最佳答案
这段代码有点棘手,因此您会发现其中的一些内容令人费解也就不足为奇了。要理解它,你需要理解closures . this answer 中有一些关于 Python 闭包的信息.
init_instance
使用 instance = make_instance(cls)
创建一个新实例,然后它查找 cls< 的
,如果它存在,它会使用新实例和 init
方法args
中传递的任何内容调用 init
方法。 make_instance
和 init_instance
都不会修改 cls
字典,或者传递给 make_class< 的
当 attributes
字典cls
创建时。实际发生的是,每次调用 make_instance
都会为其创建的实例创建一个新的 attributes
字典,get
和 set
实例字典中的函数可以引用。
您的 make_my_class
定义没有多大意义。它有一个冗余的 pass
语句,并且 make_class({'__init__': __init__})
不会工作,因为你还没有定义 __init__
在任何地方,它都需要是一个函数来初始化你的类实例。
这是您的代码的修改版本。我为 my_class
创建了一个简单的 __init__
函数,并添加了几个 print
调用,以便我们了解代码的作用。
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
关于python - 类实例实现,初始化实例——来自SICP python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50769327/