框架和对象之间有什么区别,什么时候应该修改其中一个而不是另一个?

2024-04-17

我开始阅读有关 python 的 += 语法的内容,并偶然发现了以下帖子/答案:关于+=的交互代码 https://stackoverflow.com/a/13329969/7143036

所以我注意到框架和物体之间似乎存在差异。

在全局框架中,即使它们是不同的变量,它们也指向同一个对象;如果线

l2 += [item]

相反

l2 = l2 + [item]

那么当该行运行时,“l2”将成为一个单独的对象。我最大的问题是你什么时候想要一个变量指向一个单独的对象?另外,为什么以及什么时候你想让它们指向同一个对象?

任何解释或用例将不胜感激!如果您能提及与数据科学相关的任何内容,请额外感谢:)


frame and object并不意味着你认为他们的意思。

在编程中你有一个叫做stack。在Python中,当你调用一个函数时,你会创建一个叫做栈帧。该框架(如您在示例中所见)基本上只是一个包含函数本地所有变量的表。

注意defining函数不会创建新的堆栈帧,它是calling一个函数。例如这样的事情:

def say_hello():
    name = input('What is your name?')
    print('Hello, {}'.format(name))

你的全局框架只会保存一个参考:say_hello。通过检查本地命名空间中的内容,您可以看到这一点(在 Python 中,命名空间、作用域和堆栈帧之间几乎具有 1:1 的关系):

print(locals())

你会看到类似这样的东西:

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1019bb320>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/private/tmp/fun.py', '__cached__': None, 'say_hello': <function say_hello at 0x101962d90>}

请注意 dunder(双下划线双下划线的缩写)名称 - 这些名称是自动提供的,出于我们讨论的目的,您可以忽略它们。这给我们留下了:

{'say_hello': <function say_hello at 0x101962d90>}

That 0xbit 是函数本身所在的内存地址。所以在这里,我们的全局堆栈/帧仅包含该一个值。如果你调用你的函数然后检查locals()再次,你会看到name不在那里。这是因为当您调用该函数时,您会创建一个新的堆栈帧,并在其中分配变量。您可以通过添加来证明这一点print(locals())在你的函数结束时。然后你会看到这样的东西:

{'name': 'Arthur, King of the Brits'}

这里没有重复的名字。您还会注意到,这不显示内存地址。如果你想知道这个值在哪里,可以使用一个函数。

def say_hello():
    name = input('What is your name?')
    print('hello {}'.format(name))
    print(locals())
    print(id(name))
    return name

print(id(say_hello()))

这就是这个例子在谈论一个问题时的意思。frame.

但是物体呢?嗯,在Python中,一切是一个对象。去尝试一下:

>>> isinstance(3, object)
True
>>> isinstance(None, object)
True
>>> isinstance('hello', object)
True
>>> isinstance(13.2, object)
True
>>> isinstance(3j, object)
True
>>> def fun():
...  print('hello')
... 
>>> isinstance(fun, object)
True
>>> class Cool: pass
... 
>>> isinstance(Cool, object)
True
>>> isinstance(Cool(), object)
True
>>> isinstance(object, object)
True
>>> isinstance(isinstance, object)
True
>>> isinstance(True, object)
True

They're all对象。但它们可能是不同的对象。你怎么知道呢?和id:

>>> id(3)
4297619904
>>> id(None)
4297303920
>>> id('hello')
4325843048
>>> id('hello')
4325843048
>>> id(13.2)
4322300216
>>> id(3j)
4325518960
>>> id(13.2)
4322300216
>>> id(fun)
4322635152
>>> id(isinstance)
4298988640
>>> id(True)
4297228640
>>> id(False)
4297228608
>>> id(None)
4297303920
>>> id(Cool)
4302561896

请注意,您还可以比较两个对象是否是same对象通过使用is.

>>> True is False
False
>>> True is True
True
>>> 'hello world' is 'hello world'
True
>>> 'hello world' is ('hello ' + 'world')
False
>>> 512 is (500+12)
False
>>> 23 is (20+3)
True

呃呃……?等一下,那里发生了什么?好吧,事实证明,python(即CPython)缓存小整数 https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers。所以对象512与对象不同的是对象的结果500添加到对象12.

需要注意的一件重要事情是赋值运算符= always分配一个新名称同一个物体。例如:

>>> x = 592
>>> y = 592
>>> x is y
False
>>> x == y
True
>>> x = y
>>> x is y
True
>>> x == y
True

无论你给一个对象赋予多少个其他名称,或者即使你通过了物体围绕不同的框架 https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument,你仍然有相同的对象。

但当您开始收集时,了解以下操作之间的区别非常重要:change一个对象和产生一个的操作new目的。一般来说,你有一个一些不可变类型 https://docs.python.org/3/reference/datamodel.html在Python中,对它们的操作将产生一个新对象。

至于你的问题,你什么时候想改变对象,什么时候你想保持它们不变,实际上是错误的看待方式。当您想要更改内容时,您希望使用可变类型;如果您不想更改内容,则希望使用不可变类型。

例如,假设您有一个群组,并且您想要向该群组添加成员。您可以使用可变类型(例如列表)来跟踪组,并使用不可变类型(例如字符串)来表示成员。像这样:

>>> group = []
>>> id(group)
4325836488
>>> group.append('Sir Lancelot')
>>> group.append('Sir Gallahad')
>>> group.append('Sir Robin')
>>> group.append("Robin's Minstrels")
>>> group.append('King Arthur')
>>> group
['Sir Lancelot', 'Sir Gallahad', 'Sir Robin', "Robin's Minstrels", 'King Arthur']

当团体成员被吃掉时会发生什么?

>>> del group[-2]  # And there was much rejoicing
>>> id(group)
4325836488
>>> group
['Sir Lancelot', 'Sir Gallahad', 'Sir Robin', 'King Arthur']

您会注意到,您仍然拥有相同的组,只是成员发生了变化。

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

框架和对象之间有什么区别,什么时候应该修改其中一个而不是另一个? 的相关文章

  • 在 Python 3 中动态导入模块的问题

    我遇到的情况是 在我的 Python 3 项目中 在运行时必须包含某些模块 我在用着importlib import module为了这 第二次更新 我确实找到了一种方法来做一些接近我想要的事情 一些额外的代码可能会使我的一些链接稍微偏离一
  • 可移植的非关系数据库

    我想尝试 尝试非关系数据库 最好的解决方案是 便携式 这意味着它不需要安装 理想情况下 只需将目录复制粘贴到某个地方即可使其工作 我不介意第一次使用时是否需要编辑一些配置文件或运行配置工具 可从 python 访问 适用于 Windows
  • Pandas Pivot_Table :非数字值的行计算百分比

    这是我在数据框 df 中的数据 Document Name Time SPS2315511 A 1 HOUR SPS2315512 B 1 2 HOUR SPS2315513 C 2 3 HOUR SPS2315514 C 1 HOUR S
  • angular.copy() 和 JSON.parse(JSON.stringify()) 之间的区别?

    有人可以解释 angular copy 和 JSON parse JSON stringify 之间的区别吗 有吗 您会推荐使用什么 angular fromJson angular toJson 与 JSON parse JSON str
  • 向 Python 2.6 添加 SSL 支持

    我尝试使用sslPython 2 6 中的模块 但我被告知它不可用 安装OpenSSL后 我重新编译2 6 但问题仍然存在 有什么建议么 您安装了 OpenSSL 开发库吗 我必须安装openssl devel例如 在 CentOS 上 在
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 如何使用 msgpack 进行读写?

    如何序列化 反序列化字典data with msgpack http msgpack org The Python 文档 http msgpack python readthedocs io en latest badge latest似乎
  • 管理文件字段当前 url 不正确

    在 Django 管理中 只要有 FileField 编辑页面上就会有一个 当前 框 其中包含指向当前文件的超链接 但是 此链接会附加到当前页面 url 因此会导致 404 因为不存在这样的页面 例如 http 127 0 0 1 8000
  • 有没有任何方法可以使用 openpyxl 获取 .xlsx 工作表中存在的行数和列数?

    有没有任何方法可以使用 openpyxl 获取 xlsx 工作表中存在的行数和列数 在xlrd中 sheet ncols sheet nrows 将给出列数和行数 openpyxl中有这样的方法吗 给定一个变量sheet 可以通过以下方式之
  • 如何在 Python 中仅列出 zip 存档中的文件夹?

    如何仅列出 zip 存档中的文件夹 这将列出存档中的每个文件夹和文件 import zipfile file zipfile ZipFile samples sample zip r for name in file namelist pr
  • Flask SQLAlchemy 与 MyPy - 模型类型错误

    我遇到了以下组合问题flask sqlalchemy and mypy 当我定义一个新的 ORM 对象时 例如 class Foo db Model pass where db是使用创建的数据库SQL炼金术应用于flask app mypy
  • 向量化 numpy bincount

    我有一个 2d numpy 数组 A我要申请np bincount 到矩阵的每一列A生成另一个二维数组B由原始矩阵每列的 bincounts 组成A 我的问题是 np bincount 是一个采用一维数组的函数 它不是像这样的数组方法B A
  • 从 csv 中读取 pandas 数据帧,以非固定标头开始

    我有许多数据文件是由我的实验室中使用的一些相当黑客的脚本生成的 该脚本非常有趣 因为它在标头之前附加的行数因文件而异 尽管它们具有相同的格式并具有相同的标头 我正在编写一个批处理来将所有这些文件处理为数据帧 如果我不知道位置 如何让 pan
  • psutil:测量特定进程的CPU使用率

    我正在尝试测量进程树的 cpu 使用率 目前获取进程 没有子进程 的 cpu usage 就可以了 但我得到了奇怪的结果 import psutil p psutil Process PID p cpu percent 还给我float g
  • 将函数应用于每个列组合

    我有一个数据框n列并希望对每个列应用一个函数组合列 这与如何cor 函数将数据帧作为输入并生成相关矩阵作为输出 例如 X lt data frame A rnorm 100 B rnorm 100 C rnorm 100 cor X 这将生
  • 在 scrapy 中将基本 url 与结果 href 结合起来

    下面是我的蜘蛛代码 class Blurb2Spider BaseSpider name blurb2 allowed domains www domain com def start requests self yield self ma
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • 查找“与我共享”文件夹 ID(驱动器 ID)和文件 - OneDrive、Microsoft Graph、Python

    我的客户与我共享了一些onedrive文件夹 其中包含5个文件 我想找到drive Id File Id 以便我可以使用python脚本下载 脚本参考 无法从内部文件夹 OneDrive Microsoft Graph Python 下载文
  • 如何让你的精灵在pygame中跳跃

    目前我已经制作了一个平台游戏 可以左右移动我的角色 他从地上开始 关于如何让他跳的任何想法 因为我不明白 目前 如果我按住向上键 我的玩家精灵将连续向上移动 或者如果我按下它 我的玩家精灵将向上移动并保持向上 我想找个办法远离他 让我重新跌
  • Selenium Python 使用代理运行浏览器[重复]

    这个问题在这里已经有答案了 我正在尝试编写一个非常简单的脚本 该脚本从 txt 文件获取代理 不需要身份验证 并用它打开浏览器 然后沿着代理列表循环此操作一定次数 我确实知道如何打开 txt 文件并使用它 我的主要问题是让代理正常工作 我见

随机推荐