python 变量作用域 v.__sizeof__() python 深复制 一切皆对象 尽量减少内存消耗 赋值语句的原理 __new__ __init__
小结:
1、
+=修改旧变量地址的内容;=创建新增内存地址;
1、
id cpy 内存地址
2、赋值语句的原理
不复制对象,而是建立目标和对象的绑定。
Assignment statements in Python do not copy objects, they create bindings between a target and an object.
2、
对象是由 __new__()
创建并由 __init__()
定制构造完成。
3. 数据模型 — Python 3.11.3 文档 https://docs.python.org/zh-cn/3/reference/datamodel.html?highlight=_new_#object.__new__
- object.__new__(cls[, ...])
-
调用以创建一个 cls 类的新实例。
__new__()
是一个静态方法 (因为是特例所以你不需要显式地声明),它会将所请求实例所属的类作为第一个参数。其余的参数会被传递给对象构造器表达式 (对类的调用)。__new__()
的返回值应为新对象实例 (通常是 cls 的实例)。Typical implementations create a new instance of the class by invoking the superclass's
__new__()
method usingsuper().__new__(cls[, ...])
with appropriate arguments and then modifying the newly created instance as necessary before returning it.如果
__new__()
在构造对象期间被发起调用并且它返回了一个 cls 的实例,则新实例的__init__()
方法将以__init__(self[, ...])
的形式被发起调用,其中 self 为新实例而其余的参数与被传给对象构造器的参数相同。如果
__new__()
未返回一个 cls 的实例,则新实例的__init__()
方法就不会被执行。__new__()
的目的主要是允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程。它也常会在自定义元类中被重载以便定制类创建过程。
- object.__init__(self[, ...])
-
在实例 (通过
__new__()
) 被创建之后,返回调用者之前调用。其参数与传递给类构造器表达式的参数相同。一个基类如果有__init__()
方法,则其所派生的类如果也有__init__()
方法,就必须显式地调用它以确保实例基类部分的正确初始化;例如:super().__init__([args...])
.因为对象是由
__new__()
和__init__()
协作构造完成的 (由__new__()
创建,并由__init__()
定制),所以__init__()
返回的值只能是None
,否则会在运行时引发TypeError
。
python 深入理解 赋值、引用、拷贝、作用域 - 江召伟 - 博客园 https://www.cnblogs.com/jiangzhaowei/p/5740913.html
a=[1,2,5]
b=a
print(id(a),'--',id(b))
b=[9,8]
print(id(a),'--',id(b))
f=7
g=f
print(id(f),'--',id(g))
g=888
print(id(f),'--',id(g))
class c:
def __init__(self,a):
self.a=a
def f(self):
print(self.a)
c1=c(66)
c2=c('str')
print(id(c1),'--',id(c2))
class cb:
def __init__(self):
self.a=a
def f(self):
print(123)
cb1=cb()
cb2=cb()
print(id(cb1),'--',id(cb2))
import copy
gg=9
内存地址 内存标识 内存id
1794696 -- 1794696
1794696 -- 1794760
8791475577680 -- 8791475577680
8791475577680 -- 2024944
31727120 -- 31727176
31727288 -- 31727232
一切皆对象
尽量减少内存消耗
id 内存地址
id
(object)¶
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id()
value.
CPython implementation detail: This is the address of the object in memory.
copy — Shallow and deep copy operations — Python 3.8.2rc1 documentation https://docs.python.org/3.8/library/copy.html
Assignment statements in Python do not copy objects, they create bindings between a target and an object.
a = b = c = 1 e, d, f = 1, 1, 1 a = 4 a1 = b1 = c1 = '1' e1, d1, f1 = '1', '1', '1' a1 = '2' import copy x = copy.deepcopy(a) z = copy.copy(a) y = a a = 5 x1 = copy.deepcopy(e1) z1 = copy.copy(e1) y1 = e1 e1 = '2' lc = [1, [2, 3]] lc1 = copy.copy(lc) lc2 = copy.deepcopy(lc) lc = [1, [2, 3, 4]] dc = {'a':12,12:'a'} dc1 = copy.copy(dc) dc2 = copy.deepcopy(dc) dc = {'a':123,12:'ab'} dcr = {'a':12,12:'a'} dcr0=dcr dcr1 = copy.copy(dcr) dcr2 = copy.deepcopy(dcr) dcr = {'a':123,12:{1:1,'a':'a'}} dcrr = {'a':123,12:{1:1,'a':'a'}} dcrr0=dcrr dcrr1 = copy.copy(dcrr) dcrr2 = copy.deepcopy(dcrr) dcrr = {'a':123,12:{11:1,'aa':'aa'}} t = 7
上述赋值语句 右边值的改变均没有引起左边值的改变。
The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):
-
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
-
A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
Two problems often exist with deep copy operations that don’t exist with shallow copy operations:
-
Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
-
Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.
The deepcopy()
function avoids these problems by:
-
keeping a
memo
dictionary of objects already copied during the current copying pass; and -
letting user-defined classes override the copying operation or the set of components copied.
关于Python中的引用 - 东去春来 - 博客园 https://www.cnblogs.com/yuyan/archive/2012/04/21/2461673.html
x,y=1,2
x,y=y,x+y
生成器 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/1016959663602400/1017318207388128
注意,赋值语句:
a, b = b, a + b
相当于:
t = (b, a + b) # t是一个tuple
a = t[0]
b = t[1]
但不必显式写出临时变量t就可以赋值。
The deepcopy()
function avoids these problems by:
-
keeping a
memo
dictionary of objects already copied during the current copying pass; and -
letting user-defined classes override the copying operation or the set of components copied.
This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, or any similar types. It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle
module.
Shallow copies of dictionaries can be made using dict.copy()
, and of lists by assigning a slice of the entire list, for example, copied_list = original_list[:]
.
Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle
for information on these methods. In fact, the copy
module uses the registered pickle functions from the copyreg
module.
In order for a class to define its own copy implementation, it can define special methods __copy__()
and __deepcopy__()
. The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo
dictionary. If the __deepcopy__()
implementation needs to make a deep copy of a component, it should call the deepcopy()
function with the component as first argument and the memo dictionary as second argument.
See also
- Module
pickle
-
Discussion of the special methods used to support object state retrieval and restoration.