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

2024-01-26

我试图理解Python类系统实现中的初始化函数,摘自本书(SICP python - 参考书籍部分) http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/objects.html#instances.

The init_instance(初始化)函数"""Return a new object with type cls, initialized with 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):将类定义中的函数绑定到对象实例以模拟 python 类实例中的 python 方法。如果 value 不可调用,则返回 value (来自父类的 python 属性)。
  • make_class (attributes, base_class = None):设置类的行为,具有从另一个类继承的能力。使用 get 和 set 的方式与 make_instance 类似,但它不需要 bind_method。它用init_instance(cls, *args)创建具有任意数量参数的新对象实例(对于属性的方法)。cls论证init_instance将类调度字典传递给对象实例。因此,对象“继承”(由于缺乏更好的词)类特征。
  • init_instance(cls, *args): 说到这里我有点不确定了。首先,该函数创建一个实例instance = make_instance(cls),实例通过继承类的特性cls字典。init = cls['get']('__init__') , init创建一个语句,查找 if__init__关键字在属性中传递给make_class, , if init: init(instance, *args)使 args 成为实例本地的?返回一个实例。

我可以将我的问题缩小到 -

init_instance是回到new(*args) in make_class。这意味着实例字典被返回到new(*args)。然而,make_class回报cls这意味着我们必须更新cls以某种方式遏制instance特性。这是怎么做到的?最有可能的是这个说法init (instance, *args)但我不知道如何分解这个陈述。我没见过init作为 fn,如何将参数传递给它?


这段代码有点棘手,所以您发现其中一些令人费解也就不足为奇了。要理解它,你需要理解closures https://en.wikipedia.org/wiki/Closure_%28computer_programming%29。有一些关于 Python 中的闭包的信息这个答案 https://stackoverflow.com/a/20898085/4014959.

init_instance创建一个新实例instance = make_instance(cls),然后它查找init的方法cls,如果存在,则称为init使用新实例和传入的任何内容的方法args。两者都不make_instance nor init_instance修改cls字典,或者attributes传递给的字典make_class when cls被创建。实际发生的是每次调用make_instance创建一个新的attributes它创建的实例的字典,其中get and set实例dict中的函数可以引用。

Your make_my_class定义没有多大意义。它有一个冗余pass声明,以及make_class({'__init__': __init__})不会工作,因为你还没有定义__init__在任何地方,它都需要是一个将初始化类实例的函数。

这是您的代码的修改版本。我创建了一个简单的__init__函数为my_class,并添加了几个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'))

output

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类实例实现,初始化实例 - 来自 SICP python 的相关文章

随机推荐

  • onKey onKeyDown 不起作用

    我正在尝试在我的 Android 应用程序中注册方向键 电视遥控器方向键点击 我目前正在使用 Android 模拟器进行测试 并尝试在额外设置菜单下使用方向键输入进行单击 但我不确定为什么这不起作用 任何帮助将不胜感激 public cla
  • 如何使用 Java 复制文件并将其粘贴到剪贴板?

    如何使用 Java 复制文件并将其粘贴到剪贴板 我的程序可以复制但不能粘贴 它给 线程 main 中的异常 java lang ClassCastException java util Arrays ArrayList 无法转换为 java
  • Plotly.js - gd.data 必须是一个数组

    我正在使用 Plotly js 库来绘制 3D 图形 我的计划是将 4 条迹线绘制到一张 3D 图中 但是当我尝试这样做时 我的网站遇到了一些奇怪的行为 有时 当我加载网站时 我没有收到任何错误 并且所有 4 条轨迹都完美加载到我的 3D
  • 将 GWT 应用程序部署为单个 JavaScript 文件

    GWT 应用程序的已编译 JavaScript 输出分为不同的文件 例如 缓存 html gwt rpc 托管 html nocache js 我知道这样做的目的是最小化必须由用户下载的 JavaScript 的大小 例如 Firefox
  • 更新表插入 VARBINARY 数据

    当我运行 sql 查询时 我得到如下信息 不允许从数据类型 varchar 到数据类型的隐式转换 varbinary 使用 CONVERT 函数运行此查询 严重程度 16 我想要插入的数据看起来像 000012000000000000100
  • 如何使用 Windows 任务计划程序自动执行 PowerShell 脚本?

    我有一个发送电子邮件的 PowerShell 脚本 我想每 1 分钟自动执行一次该脚本 我该如何使用任务计划程序来做到这一点 目前我已经创建了一个任务并提供了脚本的路径 但是该调度程序打开我的脚本 而不是执行 我使用的是 Windows 7
  • JDK8 是 JBoss 6 AS 支持的平台吗

    我们正在将应用程序 java 平台升级到最新的稳定平台 并且我们正在使用 Jboss 6 AS Is 甲骨文JDK8JBoss 6 AS 支持的平台 不 它不会起作用 JBoss AS 6和 7 不兼容Oracle JDK 1 8 您需要下
  • 阻止 GSON 序列化 JSON 字符串

    我是 gson 的新手 并且有一个尚未找到答案的新手问题 所以请耐心等待 StackOverflow 和 google 不是我的朋友 我有一个 java 类 User 其属性之一 externalProfile 是一个包含已序列化 JSON
  • 为什么 MFunctor 的“hoist”没有“Monad n”约束?

    我有一个协程变压器 data Step y m a Done a Yield y CoT y m a data CoT y m a CoT m Step y m a with Monad实例 unCoT CoT y m a gt m Ste
  • Laravel - 针对不同用户使用唯一参数重复输入

    使用 Laravel 5 2 我正在 Laravel 中开发一个电话簿项目 您将联系信息存储在名为的表中Contacts 要在此表中创建新联系人 您必须注册 并且您的信息将记录在users table 我创建了一个视图来显示Contacts
  • Firemonkey T编辑高度

    我正在使用 Delphi Seattle 我的应用程序适用于 Windows 桌面 我正在尝试更改 TEdit 的字体大小 因此高度也被修改 在设计时一切正常 但当我运行应用程序时 TEdit 会忽略高度修改并剪切文本 我试图找到Fixed
  • NEWSEQUENTIALID 的可预测性如何?

    根据微软的文档NEWSEQUENTIALID http msdn microsoft com en us library ms189786 aspx NEWSEQUENTIALID 的输出是可预测的 但可预测性如何呢 假设我有一个 GUID
  • sed 中的反向引用返回错误值

    我正在尝试使用 sed 替换表达式 正则表达式在 vim 中有效 但在 sed 中无效 我用斜杠替换数字前的最后一个破折号 所以 www file name 1 应该返回 www file name 1 我正在使用以下命令 但它一直输出 w
  • Apache Camel HTTP 显示请求和响应

    我正在使用 Apache Camel 将数据从 CSV 文件加载到 Web 服务 无论如何我可以显示请求和响应 下面是路由配置 我从数组中拆分并聚合 100 个项目 以作为 POST 正文发送 from fileLocation unmar
  • SqlAlchemy TIMESTAMP“更新时”额外

    我在 python3 4 3 上使用 SqlAlchemy 来管理 MySQL 数据库 我正在创建一个表 from datetime import datetime from sqlalchemy import Column text cr
  • 今日小部件扩展高度 - iOS10

    今日小部件视图模式的高度无法设置为紧凑模式 无论我设置什么值 它将小部件的高度设置为默认值 扩展模式工作完美 并且值已正确设置并反映在小部件中 我已经在 viewDidLoad 方法中添加了这一行 self extensionContext
  • 生产中使用 Flask-oauthlib 或 authlib?

    我刚刚在我正在构建的网站上使用了flask oauthlib 但是 我注意到该项目的首页有一个警告 要求改为使用 authlib 如果您在生产中使用flask oauthlib 您是否计划迁移到authlib 有谁知道一个完成此迁移的简单项
  • 流式源的查询必须使用 writeStream.start() 执行;

    我正在尝试在 Spark 中读取来自 kafka 版本 10 的消息并尝试打印它 import spark implicits val spark SparkSession builder appName StructuredNetwork
  • 对于 Android 4.4 及以上版本,使用 Crosswalk 有什么真正的好处吗?

    Crosswalk 插件对于为混合应用带来巨大的性能提升非常重要 但问题是 一旦添加 APK 就会变得巨大 给安装程序增加了大约 15 18MB 的大小 那么 将人行横道添加到 Android 4 4 及更高版本的安装程序中是否有任何真正的
  • 类实例实现,初始化实例 - 来自 SICP python

    我试图理解Python类系统实现中的初始化函数 摘自本书 SICP python 参考书籍部分 http www inst eecs berkeley edu cs61a sp12 book objects html instances T