Python学习——"Python高级(一)"

今天已经开始接触Python高级的知识了,依旧照例,依旧进行我们的知识回顾与总结,废话不多说,开始我们的战斗!

1、包和模块

在我们接触到一个新名词时,我们第一个要做的事情就是要明白这个名称是什么?那什么是包和模块呢?其实这在我们Python中很常见。

 **包(package):在python中,用来包裹模块的文件夹。**

在python中,文件夹是可以当成包使用的,但包并不是文件夹!!

在python中,如果一个文件夹中存在__init__.py这个模块文件的话,这个文件夹就是包,init.py一般用来初始化文件

**模块(module):xx.py文件, 保存是要执行或者使用代码。**

了解了包和模块的概念,我们要知道它们的使用方法,这里说一下常见的导包方式。

	1、import package.module
	
	2、import package.module as alias
	
	3、**from package import module**        (推荐这种导包方式)
	
	4、from package import module as alias
	
	5、from package.package... import module as alias
	
	6、from package import *		# 通配所有

2、is和==的区别

is和==有什么区别呢?

首先两者都是判断变量的,但是!

is判断的是两个变量的内存地址

==判断的两个变量的值

小整形缓存区(-5~256)

3、深浅拷贝

接下来说说深浅拷贝,这里我们要了解三个概念,分别是赋值、浅拷贝、深拷贝。接下来我分别说下这三个知识点。

1、赋值

赋值:主要的操作,栈内存的复制。

赋值在Python中就太常见了,我们很多操作都需要用到赋值,如果不赋值,有时我们就无法完成我们程序。

>>>a = "宋同学"               #把宋同学赋值给a
>>>b = a                          #把a的值赋给b
>>>b == a                        #a等于b
>>>true                            #结果正确

这就是赋值。

2、浅拷贝
接下来来说说深拷贝和浅拷贝。实现要明白两者的本质区别,这里我自己通俗的理解就是。

浅拷贝的对象与源对象两者还是有联系的,但是深拷贝的对象与源对象则是完全没有联系,是一个新的对象。

如果是一个列表:ls2 = ls.copy()
浅拷贝对象,并不是完全把对象拷贝,而是仅仅拷贝了第一层对象,如果对象中存储有子对象,那么两者还是有联系的。

3、深拷贝

深拷贝使用递归的方式完成的拷贝,这样,两个对象之间没有任何关系,并不存在联系。

拷贝对象,对象是存储在堆中的,拷贝堆内存,需要得到第二个一样的对象,复制拷贝对象的效率最高。

当然,我们Python中为了提供对象拷贝,专门为大家提供了一个copy模板。

copy.copy       #浅拷贝,相当于列表中cpoy方法

理论上讲解是这样的,可能还不够明显的变现出两者的区别,在这里,用一个展示来变现下两者的区别。

>>>ls = [2020,4,10]   #创建一个列表
>>>ls1 =copy.copy(ls) #浅拷贝
>>>ls2 =copy.deepcopy(ls) #深拷贝
>>>ls.append(4) #往列表ls追加4
>>>ls1 			#查看列表1
>>>[2020,4,10]
>>>ls2			#查看列表2
>>>[2020,4,10]
>>>ls 			#查看列表ls
>>>[2020,4,10,4]
>>>ls is ls1
>>>False
>>>ls is ls2
>>>False

没有嵌套时,深浅拷贝都是复制堆里的数据,产生新的地址。

列表深浅拷贝,都产生新的数据堆,浅拷贝嵌套的第二层指向同一个数据,深拷贝是递归拷贝,产生新的数据堆。

元组浅拷贝,只拷贝第一层,第一层是元组,元组不可变,只有一个内存,嵌套的第二层指向同一个数据。

深拷贝是递归拷贝,所有的都拷贝了。

在这里特表要注意的两点!
1、需要将当前对象拷贝的时候,一般建议拷贝为浅拷贝,(效率高,内存占有少)
2、如果说,就是需要完全分离,请使用深拷贝。

最后的结论:

元组、字符串、数值这些不可变类型,所有深浅拷贝后,永远只有一份内存==注意特殊情况,如元组中的存在可变类型的元素

4、生成器

接下来说说生成器,这里要说几个东西,分别是列表推导器、列表生成器、以及函数转换为列表生成器和yield关键字的作用。

1、列表推导器
[ x for x in range(101)]
[ i for i in range(101) if i % 2 == 0]
[ i*j for i in range(10) for j in range(10)]
这个功能非常的强大,可以快速得到需要的列表。
缺点:如果一个列表特别的庞大,这样所有的元素直接初始化到内存中,引起大量无用元素占有内存问题

>>>[i for i in range(6)]
>>>[0,1,2,3,4,5]
>>>[i for i in range(6) if i%2==1]
>>>[1,3,5]

2、列表生成器(list generator)
列表推导式 —> 生成器
[ 列表推导式 ] --> (列表推导式) # 就会变成一个列表推导式,使用全局函数next,没调用一次next,返回下一个值,直到最后抛出异常。
(1)
1
(2)也可以使用循环迭代generator
2
(3)生成器对象也存在一个__next__魔方方法,等价于next全局函数

优点:节约内存

3

3、函数转换为列表生成器
当列表生成时,需要大量代码来完成时,不可能使用列表推导式,一般使用函数完成,如:(斐波那契数列)

斐波那契数列:
从第三个元素开始,每一个元素是前两个元素之和,【 如果函数中使用yield关键字,那么这个函数的返回值就是一个生成器】

4、yield关键字作用
1、 具有return的功能,能够返回一个函数的值。

2、 当一个函数出现yield,那么这个函数就被调用执行,而是返回值是一个生成器。

3、 next它返回值,不断地返回被yield的值
yield值之后,会记住当前位置,下一次next函数调用生成器的时候,会在记住的位置继续执行。

def fibonacii(num):
first, second = 1, 1
index = 0
while index < num:
    first, second = second, first + second
    # 如果函数中使用yield关键字,那么这个函数的返回值就是一个生成器
    yield first
    index += 1
    if __name__ == '__main__':

res = fibonacii(5)
print(res)  
 #<generator object fibonacii at 
 0x000001603925DFC0>使用yield关键字装饰的函数,
 当调用函数时,函数本身并不会调用,而是将函数转换为
 一个生成器返回
print(next(res))
print(next(res))
print(next(res))
print(next(res))
print(next(res))

5、迭代器

迭代是访问容器元素的一种方式

可迭代对象(Iterable)
以后需要迭代一个对象

from collections.abc import Iterable, Iterator
t = 对象
if isinstance(t, Iterable):
for i in t: # 迭代对象
else:
print("对不起,该对象不能迭代")

【迭代器】
在python,能够被全局函数next调用,并且返回下一个值的对象,就是迭代器。

迭代器
可迭代对象不一定是迭代器,迭代器都是可迭代对象

结论:
1、凡是可作用于 for 循环的对象都是 Iterable 类型;
2、凡是可作用于 next() 函数的对象都是 Iterator 类型
3、可迭代对象不一定是迭代器,迭代器都是可迭代对象
4、集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,
5、不过可以通过iter() 函数获得一个 Iterator 对象。
6、目的是在使用迭代器的时候,减少内存的占用。

6、闭包

闭包(closure)

	闭包是一种现象,是若数据类型编程语言所特有的现象。
JavaScript(js)时时刻刻在使用闭包

概念: 能够在函数内部调用其他函数变量的现象就闭包

函数包裹函数的现象,就叫做闭包

作用:让外层函数常驻内存,有可能垃圾无法回收,让局部变量全局化

def father():
'''
    这个函数就是一个闭包
'''
print("这个是一个闭包")
a = 10
def son():
    print("这个是里面函数的代码")
    b = 20
    print(a + b)

return son   #返回一个地址


res = father()   #调用father(),并没有调用son()
print(res)  #<function father.<locals>.son at 	0x000002E8022E8AE8>是return返回的地址

res()

还有几个内容,我放到Python高级(二)中来说,今天又是奥里给的一天,大家加油!明日可期。

下一篇Python高级(二)中会说到装饰器、动态语言的特性、垃圾回收机制、常见的内置模块、常见的全局函数和正则表达式。

我们下一篇文章见,那么我不在的日子,祝你早好,午好,晚好,我们下次见了,bye~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值