摘要:结果为对于迭代器和生成器你知道哪些,它们分别应用于什么场景先介绍什么是可迭代的任何可用于循环的都是可迭代的。示例结果为,迭代器任何可以使用函数的都是迭代器,也可使用函数将可迭代对象变为迭代器。未写完,下次更新补上。
阅读本文大约需要 8 分钟。7.说一下 Python 中的装饰器
原理:利用闭包,将目标函数外面再套一层函数,使得目标函数具有一个新的功能,并且不改变目标函数原有功能。
实现方式:
闭包
def decorate(func): def wrapper(): print("新功能") func() return wrapper def func(): print("原有功能") f = decorate(func) f() # 结果为: 新功能 原有功能
@ 语法糖
def decorate01(func): def wrapper(): print("新功能") func() return wrapper @decorate01 def func01(): print("原有功能") func01() # 结果为: 新功能 原有功能
8.说一说类属性、实例属性、私有属性和保护属性类属性相当于全部变量,所有由类创建出来的实例,都可以使用,而实例属性相当于局部变量,只能由该实例自己使用,当类属性与实例属性命名一样时,在调用该同名属性时,会屏蔽掉类属性,调用实例属性,这点跟 LEGB 很像。
当通过实例对象来修改类属性时,其实修改的并不是类属性,而是新建了一个跟类属性名一样的实例属性。
Python 中将以两个下划线__开头,但不以两个下划线结尾的变量,认作为私有属性,Python 通过 name manage算法,将该私有属性的引用更改为_classname_reference,用户试图调用该私有属性时,会因为对象引用不一样而找不到该属性,故而实现了「属性私有化」。
在获取实例属性时,一般采用定义一个实例方法的方式获取属性,避免直接对实例属性进行操作,起到一个保护属性的作用。
9.为什么说 Python 是动态语言,鸭子类型是指什么Python 相当于其他静态语言,可以在代码运行过程中,改变变量的属性。
鸭子类型指的是 Python 不用定义变量类型,只要该变量像是什么类型,那么就认为它就是什么类型,我们更多关注的是它的行为,而不是它的类型。
10.元类是什么实例都是由类创建出来,而类则是由元类创建出来。他们之间的关系相当于「奶奶-妈妈-孙子」。
示例:
class Myclass(): pass new = type("NewClass", (Myclass,), {"name": "new"}) print(new) print(new.__mro__) # 查看该类的继承情况 # 结果为( , , )
具体点的内容可以参考这篇问答:什么是元类
11.@staticmethod 和 @classmethod 的区别@staticmethod 是为类添加一个静态方法
@classmethod 是为类添加一个类方法
12.如何动态添加属性由于 Python 的特性使得程序在运行过程中,我们可以为某个对象添加属性、方法。
示例:
class Myclass: pass m = Myclass() # 为实例动态添加一个属性 m.name = "new_atribute" def func(self): return "new_function" # 为实例动态添加一个方法 m.func = func print(m.name) print(m.__dict__) # 返回 m 的所有属性,方法 # 结果为 new_atribute new_function {"func":13.对于迭代器和生成器你知道哪些,它们分别应用于什么场景, "name": "new_atribute"} # 另外一种动态添加方法 import types def func01(self): print("new_function01") # 实例 m 添加一个属性 func,而这个属性指向func()函数,故当调用 m.func 时,也就相当于调用了 func() 函数,间接实现了为 m 添加方法 func()。 m.func = types.MethodType(func, m) print(m.func()) # 结果为 new_function01
先介绍什么是可迭代的Iterable:任何可用于for循环的都是可迭代的。也可以使用collection模块下的isinstance(obj, Iterable)来检验该对象是否可迭代。
示例:
from collections import Iterable print(isinstance("abc",Iterable)) print(isinstance(123,Iterable)) # 结果为 True,False
迭代器
任何可以使用next()函数的都是迭代器,也可使用iter()函数将可迭代对象变为迭代器。
示例:
from collections import Iterator itr = iter("abc") print(type(itr)) print(isinstance(itr, Iterator)) # 结果为 Iterator,True
生成器
任何函数中含有yield关键字的都是生成器,列表生成式中的[]改为()也是一个生成器。
实现方式
示例:
g = [i for i in range(10)] print(type(g)) # 结果为 list g1 = (i for i in range(10)) print(type(g1)) # 结果为 generator def func(): for i in range(10): yield i f = func() print(f) # 结果为
生成器怎么取值,什么时候结束
生成器可以通过next(f)、f.__next__()和f.send()三种方式来取值
示例:
def func01(): for i in range(10): yield i f = func() print(next(f)) print(f.__next__()) print(f.send("hahah")) # 结果为 0 1 2
其中f.send()可以向生成器传值,但是其第一次传入的值默认为None。如果想要取出send("hahah")里传入的值,则需要在生成器中添加接收的变量。
示例:
def func(): for i in range(10): # yield i temp = yield i print(temp) f = func() print(next(f)) print(f.__next__()) print(f.send("hahah")) # 结果为 0 None 1 hahah 2
生成器里的值被取完之后,或者中间遇到 return关键字,就会退出,这三种方法有一个共同点:当生成器取完之后会抛出StopIteration的错误。
而使用for循环来取出生成器里的值就不会抛出错误,这也是最被推荐的。
应用场景
在生成一个包含很多数(百万级别)的列表时,但是又只用得到其中很小一部分的数时,使用列表生成式会极大的浪费内存,且不一定能够生成,因为受机器内存限制。
而使用生成器则不然,生成器只是在你需要的时候,才会申请一块内存,可以边取边用,极大的降低了内存消耗。
生成器用的最多的地方在于「协程」。由于基于 C 解释器下的 Python 中含有一个 GIL 锁,使得 Pyhon 的多线程是一个假性多线程,这也是为什么很多人说 Python 性能慢的原因。
未写完,下次更新补上。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/45133.html
摘要:关于该问题的讨论今天看到的一道面试题,感觉对理解的以及原型链和闭包很有帮助。自己并试着讲述一下自己的理解,欢迎拍砖。进入上下文时,会获取,函数声明,变量声明。 2017.3.27更新今天在刷题的时候,突然发现之前已经有人在讨论这道题了,而且还涉及到了运算符优先级的问题,这是自己一开始没有想到的。(其实有人也说:程序写多了,自然记住了什么情况下会发生什么样的事情,但是为什么会发生这样的事...
摘要:第三次握手客户端收到报文之后,会回应一个报文。因此,需要三次握手才能确认双方的接收与发送能力是否正常。三次握手的作用三次握手的作用也是有好多的,多记住几个,保证不亏。也就是说,第一次第二次握手不可以携带数据,而第三次握手是可以携带数据的。在面试中,三次握手和四次挥手可以说是问的最频繁的一个知识点了,我相信大家也都看过很多关于三次握手与四次挥手的文章,今天的这篇文章,重点是围绕着面试,我们应该...
摘要:讲了一下我在电力物联网项目中通过设计的文件远程升级功能。完成聊天毕业规划怎么样收到面试调查问卷等待中。。。。。 7.31 投递提前批c++客户端岗位 8.16 被转...
阅读 1685·2023-04-26 02:30
阅读 1013·2021-11-10 11:36
阅读 1358·2021-10-08 10:14
阅读 3471·2021-09-28 09:35
阅读 1517·2021-08-23 09:47
阅读 2496·2019-08-30 15:56
阅读 1441·2019-08-30 15:44
阅读 1703·2019-08-30 13:59