gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 01:44:22 24 4
gpt4 key购买 nike

我开始阅读 python 的 += 语法并无意中发现了以下帖子/答案: Interactive code about +=

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

Frames and Objects

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

l2 += [item]

改为

l2 = l2 + [item]

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

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

最佳答案

frameobject 并不是您认为的那样。

在编程中,您有一个叫做堆栈 的东西。在 Python 中,当您调用一个函数时,您会创建一个称为堆栈框架的东西。这个框架(正如您在示例中看到的那样)基本上只是一个表,其中包含函数的所有本地变量。

请注意,定义一个函数不会创建一个新的栈帧,它是调用一个函数。例如这样的事情:

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>}

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

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

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

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

这里没有 dunder 名称。您还会注意到这不显示内存地址。如果您想知道这个值存在于何处,可以使用相应的函数。

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

print(id(say_hello()))

这就是该示例在谈论框架时的意思。

但是对象呢?好吧,在 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

它们都是对象。但它们可能是不同的对象。你怎么知道?使用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

请注意,您还可以使用 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)caches small integers .所以对象 512 不同于对象 500 添加到对象 12 的结果。

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

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

而且,您为对象指定了多少个其他名称都没有关系,即使您通过了 object around to different frames 也没有关系。 , 你仍然有相同的对象。

但是当您开始收集时,了解更改对象的操作与生成对象的操作之间的区别非常重要。一般来说你有一个 few immutable types在 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']

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

关于python - 框架和对象之间有什么区别,我什么时候应该修改一个而不是另一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40641615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com