python知识点

深拷贝和浅拷贝

浅拷贝:只是拷贝地址,即引用
在这里插入图片描述
深拷贝1:值的拷贝并创建新的空间
*copy.deepcopy()
在这里插入图片描述
深拷贝2:
列表c完成了列表a,b的嵌套,如果通过对c进行深拷贝,则深拷贝的结果e会对a,b进行怎样的操作呢?
在这里插入图片描述
验证:对a列表append一个44,从c中取a和从e中取a,发现e中的a是不变的,说明了e对列表a,b进行了深拷贝,由此表现出了’深‘的概念,即递归的拷贝。
在这里插入图片描述
copy中还有一个函数就是copy.copy,相较于copy,.deepcopy,只是完成了第一层的深拷贝,即对c进行深拷贝,而c中的a,b列表还是引用的状态,并不会递归的拷贝。
在这里插入图片描述
而且,如果copy.copy的是一个不可变类型如元组,则执行的是浅拷贝操作
在这里插入图片描述

列表

  • 当对列表进行切分(x:y)的时候,返回的是一个列表,而list[x],返回的是一个元素
  • 元组是不可变的,但位于元组中的列表仍是可变的

不可变对象

比如str,对str进行操作:

>>> a = ‘abc’
>>> a.replace(‘a’, ‘A’)
‘Abc’
>>> a
‘abc’
• 虽然字符串有个replace()方法,也确实变出了’Abc’,但变量a最后仍是’abc’,应该怎么理解呢?
• 我们先把代码改成下面这样:
>>> a = ‘abc’
>>> b = a.replace(‘a’, ‘A’)
>>> b
‘Abc’
>>> a
‘abc’
• 要始终牢记的是,a是变量,而’abc’才是’字符串对象’!有些时候,我们经常说,对象a的内容是’abc’,但其实是指,a本身是一个变量,它指向的对象的内容才是’abc’:

• 当我们调用a.replace(‘a’, ‘A’)时,实际上调用方法replace是作用在字符串对象’abc’上的,而这个方法虽然名字叫replace,但却没有改变字符串’abc’的内容。相反,replace方法创建了一个新字符串’Abc’并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串’abc’,但变量b却指向新字符串’Abc’了:
在这里插入图片描述
• 所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

参数传递

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a=“Runoob”
[1,2,3] 是 List 类型,“Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

• 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
• 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

不定长参数

即传入的参数个数是不定的,叫做不定长参数,和上述 种参数不同,声明时不会命名。

  • 1、加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
    在这里插入图片描述
  • 2、如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。
  • 3、还有一种就是参数带两个星号**,此时以字典的形式导入
    在这里插入图片描述
  • 4、声明函数时,参数中星号 * 可以单独出现,例如:
    在这里插入图片描述

遍历

items()、enumerate()、zip()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

模块导入

import搜索路径,存于sys.path中,为一个列表的形式,每个元素保存要搜索的路径,
imp–>reloa重新加载模块,否则导入之后修改模块,执行程序时模块并不会更新
循环导入导致的错误,模块a,b之间相互需要导入对方,导致死循环,为了避免这种情况,可以先完成小部分模块,且之间不能相互调用,再由总的调用各个模块

在这里插入图片描述

  • import除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字

  • Import 和from …import要求不一样,可以是类、函数、变量

  • 定义 all 变量,该变量为一列表,当用*号导入包含__all__文件的包的时候,只会导入__all__ 列表中的变量并不会导入全部的变量

一个文件下包含一个名为__init__的py文件,则次文件为包
举例:这个包的名字为t,并有一个__init__的py文件,当有很多个py文件需要导入很多相同的库的时候,可以直接导入t,且在 t 的 init 文件中导入需要的库,这样每次导入t 的时候,会自动执行 init 文件。调用时以 t. 的形式调用这些库。

入口文件:当执行a.py文件的时候,会文件a为入口文件

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
说明: 每个模块都有一个__name__属性

==、is和isinstance

== 是值的相同
is 是指向的空间相同
在这里插入图片描述
在这里插入图片描述
补充:还有一个小的点就是,大小为-6到125之间的常数,is是相同的,而超出范围就不相同了
在这里插入图片描述
instance:
当进行判断类型时,type()只能判断某个子类是否属于某个类型,而isintance()可以
在这里插入图片描述

else

for…else…当循环完了之后执行else的代码
但当for中有break时,不会执行else,它结束了当前的for循环
在这里插入图片描述

面向对象

  • 类内定义方法需要传self参数
  • 在类内方法调用类属性,需要用self.调用
    说明:self代表实例,当前对象的地址,通过self来访问实例变量或者实例方法

构造函数__init__:初始化对象属性,为特殊的实例方法,通过类的实例化来调用

  • 通过self对实例变量进行初始化,若不带self,则只是init函数的形参,并不是类的变量(看下面的验证1)
  • 可单独调用(不建议)
  • return None
类变量和实例变量

**类变量:**将变量与类绑定在一起,而不是对象
说明:__dict__字典保存对象的所有变量
作用:描述类现有的特征
比如student类,有student1,student2,,,studentn
我们可以通过类变量num来统计学生个数,是对类特征的描述(看下面的验证3)

**实例变量:**将变量与实例对象绑定在一起,用self调用

实例方法

实例方法:即实例调用的方法,用来描述类的行为

验证1:在实例方法的内部是不能调用类的变量的,这种变量查找的机制只有在类的外部调用的时候才可以
说明:我们在init函数中输出类的变量name,会报错,因为变量查找机制不适用
而用self是可以找到实例的变量的
在这里插入图片描述
在这里插入图片描述
如果要在实例方法中调用类变量,可以通过

  • 方式一:
    类名.类变量的方式调用

  • 方式二:
    self.class.类变量
    在这里插入图片描述
    在这里插入图片描述
    验证2:类变量与实例变量是不一样的
    在这里插入图片描述
    在这里插入图片描述
    验证3:类变量的作用意义
    在这里插入图片描述
    在这里插入图片描述

类方法@classmethod

实例方法使用的是self,而类方法则需要在类方法之前加@classmethod(装饰器),参数为cls(参数名字可以更改,也可为self)
所以以上验证3中对类变量就变得更加简单:
在这里插入图片描述
在这里插入图片描述
对象是允许调用类方法的

静态方法@staticmethod

静态方法不能调用实例变量,静态方法能实现的,类方法能实现

成员可见性
  • 在函数或者变量之前加__可定义为私有的,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.访问
  • 若在函数或者变量两侧都加__,则不是私有的
  • 私有变量保护机制:定义了私有变量之后,编译器会对私有变量进行改名,在dict中会显示为_类__变量,这样在外部就无法读取到,当强行对私有变量更改时,动态语言py会给类添加这个变量,而不与私有变量重名
    说明:通过查字典变量的方法,既可以查看私有变量,又能更改私有变量(所以可以说python是没有私有变量的)
    例一:更改私有变量
    在这里插入图片描述
    在这里插入图片描述
    例二:私有变量的改名
    在这里插入图片描述
    实例变量:只是将私有变量改名
    在这里插入图片描述
    例三:外部访问改名后的私有变量
    通过这一方法即可从外部访问私有变量:
    在这里插入图片描述
    在这里插入图片描述

继承

基本特性
继承:避免定义重复的方法和变量,子类和子类的实例都会继承父类的变量、方法
如果子类是空的init构造函数

  • 子类继承父类的类变量,从而子类的实例也有父类的类变量
  • 子类不能继承父类的实例变量,而子类的实例可以继承父类的实例变量
    如下,sum子类和子类的实例都可用
    而父类的实例变量子类不可用
    在这里插入图片描述
    在这里插入图片描述
子类的构造函数

实例化子类的时候,将参数传入父类的实例化函数中,需要加self
说明:init构造函数只是实例化的作用,而实例化的时候是不需要传self参数的,Human.__init__执行是类的实例化,然而并没有类的实例化这种说法,所以python会将init函数看作类中普通的方法,而方法是提供实例调用的,所以需要加self
在这里插入图片描述
如果是按照以上的方法继承,当需要更改所继承的父类时,需要更改很多处的代码,所以有了super
在这里插入图片描述
当父类和子类的方法名字冲突的时候,会默认调用子类的方法

也可用super进行调用父类的方法
在这里插入图片描述
在这里插入图片描述

闭包

闭包 = 函数 + 环境变量(函数定义时候的外部变量),闭包保存一个当时计算的现场
函数curve和环境变量a形成了一个闭包,并不会受外部a的影响
f 就是一个闭包的对象,其中的环境变量为20
在这里 插入图片描述
在这里插 入图片描述
还有一个需要注意的就是我们已经定义了环境变量,然后又在函数中定义同名的变量,此时函数就覆盖了环境变量,不能形成闭包,从而报错
在这里插入图片描述
TypeError: ‘NoneType’ object is not subscriptable

用闭包来做一个计算:旅行者每次步数的累加

global 和 nonlocal关键字
在函数中用global调用全局变量,或者nonlocal声明不用外部变量

旅行者步数的计算1:非闭包
在这里插入图片描述
然而报错:
UnboundLocalError: local variable ‘origin’ referenced before assignment

这是为什么呢?
在定义函数的时候,origin是一个左值,python会认为其为局部变量,不会去函数外部寻找作用域,所以调用函数时候执行第一句会认为局部变量未定义

所以声明其为全局变量即可:
在这里插入图片描述
旅行者步数的计算1:闭包,记住了上一次调用的状态
在这里入图片描述

匿名函数

匿名函数 = lambda表达式,冒号之后只能为表达式,不能为等号

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
    在这里插图片描述

三元表达式

在这里插入图片描述

map

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

reduce连续调用lambda进行计算

(((1+2)+3)+4)+5)
在这里插入图片描述
在这里插入图片描述

filter过滤器

True保留,False则过滤
在这里插入图片描述

装饰器

对修改是封闭的,对扩展是开放的
----开闭原则

装饰器:给函数增加功能,又不去更改函数
有点像闭包,wrapper函数装饰了decorator函数,在不更改f1函数的原则下,给f1增加新的功能
在这里插入图片描述
装饰器的最大优势:不用改变函数的调用方式
只需要在函数的前面添加@装饰函数,即可令f1函数添加了扩展功能
在这里插入图片描述
当多个函数具有不同的参数量的时候,改变装饰器的传入为可变参数类型即可兼容多个不同的函数
在这里插入图片描述
当含有关键字参数的时候装饰器:(装饰器最终版)
在这里插入图片描述
用字典实现switch
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
列表推导式:
在这里插入图片描述
列表先通过筛选在进行计算:
在这里插入图片描述
None:
None不等于空字符串、空列表、0、False,None表示不存在

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值