原标题:作为Python中级程序员,有句话不知当讲不当讲 ( ̄へ ̄)
爱你们♥
作者:Pulkit Agrawa
编译:公众号编辑部
祝妈妈们节日快乐!
这句话里有10个问题
Python中都是对象吗?
字符串是对象。列表对象。函数对象。甚至模块也是对象。任何东西都是一个对象,因为它可以赋值给一个变量或作为参数传递给一个函数。
任何可以(合法地)放在等号右边的东西都是(或创建)Python中的对象。
对象:
1、ID
2、值(可变的或不可变的)
可变的:当更改项目时,ID仍然是相同的。比如:字典、列表。
不可变的:字符串、整数、元组。
推导式
Comprehension——用于创建集合和可迭代对象的简写语法。
▍列表推导式
▍集合推导式
▍字典推导式
▍Generator 推导式
▍ If-clause 推导式
▍多重推导式
▍嵌套推导式
扩展关键字参数
在Python中调用函数时,通常必须在使用关键字参数和位置参数之间进行选择。 关键字参数通常可用于使函数调用更加明确。当我们使用关键字参数时:我们通常可以省略具有默认值的参数。
扩展形式参数语法:
扩展参数的数据类型:
扩展实参语法:
闭包和装饰器
在开始闭包之前,我们先了解一下local 函数:
适用于特殊的、一次性的功能
使得代码具有组织性和可读性
类似于lambdas,但更为一般
可能包含多个表达式
可能包含statements
▍LEGB含义解释
L-Local(function):函数内的名字空间
E-Enclosing function locals:外部嵌套函数的名字空间(例如closure)
G-Global(module):函数定义所在模块(文件)的名字空间
B-Builtin(Python):Python内置模块的名字空间
Python的命名空间是一个字典,字典内保存了变量名称与对象之间的映射关系,因此,查找变量名就是在命名空间字典中查找键-值对。
Python有多个命名空间,因此,需要有规则来规定,按照怎样的顺序来查找命名空间,LEGB就是用来规定命名空间查找顺序的规则。
LEGB规定了查找一个名称的顺序为:local-->enclosing function locals-->global-->builtin(局部变量———闭包空间———全局变量———内建模块内置)
▍Returning Function
▍闭包
维持对早期范围对象的引用。
我们可以使用_closure__来验证函数是否为闭包。
一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。在Python中,所谓的闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的 __closure__ 属性中。比如下面的代码:
__closure__ 里包含了一个元组。这个元组中的每个元素是cell类型的对象。我们看到第一个cell包含的就是整数15,也就是我们创建闭包时的环境变量b的取值。
下面看一个闭包的实际例子:
这个例子中,函数line与环境变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个环境变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。
如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。利用闭包,我们实际上创建了泛函。line函数定义一种广泛意义的函数。这个函数的一些方面已经确定(必须是直线),但另一些方面(比如a和b参数待定)。随后,我们根据line_conf传递来的参数,通过闭包的形式,将最终函数确定下来。
一个函数闭包是一个函数和一个引用集合的组合,这个引用集合指向这个函数被定义的作用域的变量。后者通常指向一个引用环境(referencing environment),这使得函数能够在它被定义的区域之外执行。在Python中,这个引用环境被存储在一个cell的tuple中。你能够通过func_closure或Python 3中的__closure__属性访问它。要铭记的一点是引用及是引用,而不是对象的深度拷贝。当然了,对于不可变对象而言,这并不是问题,然而对可变对象(list)这点就必须注意。请注意函数在定义的地方也有__globals__字段来存储全局引用环境。
▍装饰器
装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式。简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,然后返回函数或类的形式。
简单地说,decorator就像一个wrapper一样,在函数执行之前或者之后修改该函数的行为,而无需修改函数本身的代码,这也是修饰器名称的来由。
生成器和迭代协议
▍Iterable:可以将对象传递给内置的iter()函数来获得迭代器。
▍Iterator:可以将对象传递给内置的next()函数来获取下一项。
▍生成器
Python生成器是创建迭代器的一种简单方法。上面提到的都由Python中的生成器自动处理的。
生成器是一个函数,它返回一个对象(迭代器),我们可以遍历该对象(每次一个值)。
如果一个函数包含至少一个yield语句,则它将成为生成器函数。
不同之处在于,虽然return语句完全终止了一个函数,但是yield语句暂停保存函数的所有状态,然后在后续调用时继续执行。
为什么在Python中使用生成器?
Easy to Implement
Memory Efficient
Represent Infinite Stream
Pipelining Generators
上下文管理器
▍ContextManager:上下文管理器就是实现了上下文管理协议的对象。主要用于保存和恢复各种全局状态,关闭文件等,上下文管理器本身就是一种装饰器。
▍__enter__ ()
在进入with-statement主体之前调用
返回绑定到变量的值
可以返回任何类型的值
通常返回上下文管理器本身
▍__exit__()
当语句体退出时调用
__exit__(self, exc_type, exc_val, exc_tb)
@staticmethod、 @classmethod
如果需要访问函数中的类属性,请使用@classmethod。
如果不需要使用cls对象,则使用@static method。
与其他语言不同,Python中的静态方法可以在子类中重写。
继承和封装
▍继承
继承是一个类获取另一个类的属性的机制。例如,一个孩子继承了他/她父母的特点。通过继承,我们可以重用现有类的字段和方法。因此,继承促进了可重用性,并且是OOPs的一个重要概念。
▍单继承
子类将具有基类的所有功能,还可以修改和增强。
子类初始化器希望调用基类初始化器,以使整个对象被初始化。
调用其他类初始化器:
1、其他语言自动调用base class初始化器
2、Python像对待其他方法一样处理 _init__()
3、base class _init__()在被覆盖时不会被调用
4、使用super()调用 base class _init__()
isinstance(instance, class):确定对象是否具有指定的类型。
Issubclass(subclass,base class):确定一个类型是否是其他类型的子类。
▍多继承
即子类有多个父类,并且具有它们的特征:
Python如何知道应该调用哪个base class函数?
Python使用方法解析Order和super来做到这一点。
方法解析顺序
确定方法名称查找的顺序
1、通常称为“MRO”
2、方法可以在多个地方定义
3、MRO是继承图的排序
▍封装
Python包和程序设计
Sys.pathPython搜索模块的目录列表。
PYTHONPATH添加到sys.path的环境变量列表路径。
1、包是包含其他模块的模块。
2、包通常实现为包含特殊 _init__.py 文件的目录。
3、导入包时执行 __init__.py 文件。
4. 包可以包含自己实现的子包。这些子包本身是用目录中的 __init__.py 文件实现的。
5、包的模块对象具有__path__属性。
绝对导入:使用模块完整路径的导入。比如 import a,Python 会在 sys.path 里寻找所有名为 a 的顶层模块。
相对导入:使用相同包中模块的相对路径的导入。比如一个 package 下有 a.py 和 b.py 两个文件,在 a.py 里 from . import b 即是相对导入 b.py。
__all__:是一个字符串list,用来定义模块中对于from XXX import *时要对外导出的符号,即要暴露的借口,但它只对import *起作用,对from XXX import XXX不起作用。
来自:https://medium.com/@agrawal.pulkit1994
责任编辑: