Python牛客网笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZZh1301051836/article/details/89597847

1 浅拷贝与深拷贝

数据有嵌套结构时,浅拷贝与深拷贝开辟独立内存的级别不同。
例如数据:li=[1,2,[3,4]]。该数据有两层结构。
浅拷贝copy.copy():只给外层结构,开辟独立内存。(即只有外层结构内存独立,内层内存由复制品和原件共享)
深拷贝copy.deepcopy():给所有层,全部开辟独立内存。(即各层内存都独立)
示例:

import copy

a1 = [1,2,[3,4]]
b1 = copy.copy(a1)
b1[0] = 'changed1'#第一个改变的地方
b1[2][0]='changed2'#第二个改变的地方

a2 = [1,2,[3,4]]
b2 = copy.deepcopy(a2)
b2[0] = 'changed1'
b2[2][0] = 'changed2'

print(a1)
print(b1,'\n')

print(a2)
print(b2,'\n')

输出:

[1, 2, ['changed2', 4]] 
['changed1', 2, ['changed2', 4]]  #外层开辟了独立内存,所以复制品的外层变化时,原件的外层不会变。
                                                   #内层没有开辟独立内存,所以内层的内存由复制品和原件共享。

[1, 2, [3, 4]] 
['changed1', 2, ['changed2', 4]]  #全部层都开辟了独立内存,所以复制品的变化,不会影响到原件。

2 copy() & deepcopy()

常见的有三种用法:

import copy
object.copy()
copy.copy()
copy.deepcopy()

常见的用法有三种,但实际方法只有两种:copy()deepcopy()。其中,object.copy() == copy.copy()

示例1,由下面的例子可以看出object.copy() 就是 copy.copy(),copy()方法是浅拷贝,deepcopy()是深拷贝。

import copy

a1 = [1,2,[3,4]]
b1 = a1.copy()

a2 = [1,2,[3,4]]
b2 = copy.copy(a2)

a3 = [1,2,[3,4]]
b3 = copy.deepcopy(a3)

b1[2][0] = 'changed'
b2[2][0] = 'changed'
b3[2][0] = 'changed'
    

print(a1)
print(b1,'\n')

print(a2)
print(b2,'\n')

print(a3)
print(b3)

输出:

[1, 2, ['changed', 4]]
[1, 2, ['changed', 4]] 

[1, 2, ['changed', 4]]
[1, 2, ['changed', 4]] 

[1, 2, [3, 4]]
[1, 2, ['changed', 4]]

3 命名空间 LEGB

参考网址:Python LEGB规则
Python在命名空间中查找变量时,遵循LEGB规则。即LEGB规则规定了Python查找变量的顺序:

  • L— Local:函数内部
  • E—Enclosing Function local :嵌套函数内部
  • G—global:当前模块内部
  • B—builtin:内建模块

LEGB规则规定的查找名称顺序:local–>enclosing function locals–>global–>builtin。

举例:

x = 1 

def foo():
    x = 2 
    def innerfoo():
        x = 3 
        print 'locals ', x
    innerfoo()
    print 'enclosing function locals ', x

foo()
print 'global ', x
locals  3
enclosing function locals  2
global  1

稍加改动:

x = 1 

def foo():
   x = 2 
   def innerfoo():
   #    x = 3                  #此处改动:注释掉
       print 'locals ', x
   innerfoo()
   print 'enclosing function locals ', x

foo()
print 'global ', x
locals  2
enclosing function locals  2
global  1

可以发现:当注释掉x = 3以后,函数innerfoo内部查找到的x是x = 2。
在上述两个例子中,从内到外,依次形成四个命名空间:
def innerfoo()::Local, 即函数内部命名空间;
def foo()::Enclosing function locals;外部嵌套函数的名字空间
module(文件本身):Global(module);函数定义所在模块(文件)的名字空间
Python内置模块的名字空间:Builtin
x = 3 属于函数内部命名空间,当被注释掉之后,函数innerfoo内部通过print x 使用x这个名称时,触发了名称查找动作。
首先在Local命名空间查找,没有找到,然后到Enclosing function locals命名空间查找,查找成功,然后调用。

4 Python 私有、保护、共有、系统定义

_ _ foo_ _ :特殊方法,系统定义名字,例如__init__,newdel
_ _foo :私有(private),只有自己可以访问,不能用于 from module import *。Python的private与Java、C++中的不太相同,Python中的私有方法只是为了防止子类修改,但是子类仍可以通过_classname _ _ foo来访问,即“单下划线”+类名。
_foo:保护(protect),只有和其子类可以访问。
foo:公开(public),都可以访问。

记忆方法:保护性越强,写起来越麻烦。2333~

猜你喜欢

转载自blog.csdn.net/ZZh1301051836/article/details/89597847