测试是否定义过一个值 f in locals();
在 Python 中,else 语句不仅能跟 if 语句搭,构成“要么怎样,要么不怎样”的语境;Ta 还能跟循环语句(for 语句或者 while 语句),构成“干完了能怎样,干不完就别想怎样”的语境;其实 else 语句还能够跟我们刚刚讲的异常处理进行搭配,构成“没有问题,那就干吧”的语境。
使用 with 语句可以使你不比再担心文件打开后却忘了关闭的尴尬,with 语句会自动处理文件的打开和关闭,如果中途出现异常,会执行清理代码,然后确保文件自动关闭,with 语句处理多个项目的时候,可以用逗号隔开写成一条语句:
with A() as a, B() as b:
python中一行可以写多个语句,用分号(;)分开即可
逻辑操作符有个有趣的特性:在不需要求值的时候不进行操作。这么说可能比较“高深”,举个例子,表达式 x and y,需要 x 和 y 两个变量同时为真(True)的时候,结果才为真。因此,如果当 x 变量得知是假(False)的时候,表达式就会立刻返回 False,而不用去管 y 变量的值。
这种行为被称为短路逻辑(short-circuit logic)或者惰性求值(lazy evaluation)
int() 将小数转换为整数,小数取整会采用比较暴力的截断方式,即向下取整。(注:5.5 向上取整为 6,向下取整为 5)。
“四舍五入”法:int(5.4+0.5) == 5;int(5.6+0.5) == 6
Pyhton3 源码文件默认使用utf-8编码(支持中文),可以给变量命名中文名;
你好 = 'haha,我是中文变量名'
not or and 的优先级是不同的:not > and > or;
assert:断言;当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError的异常。
可以用 assert **Error
来自定断言异常类型
for i in lists:
in 是“成员资格运算符”,所以 for i in 5:
会报错;
append() 方法是将参数作为一个元素增加到列表的末尾、
extend() 方法则是将参数作为一个列表去扩展列表的末尾。
python支持负数索引,正常索引是从左到右索引,负数索引是从右到左
列表内容 | 1 | 13 | 33 | 28 | 56 | 88 |
---|---|---|---|---|---|---|
正常下标 | 0 | 1 | 2 | 3 | 4 | 5 |
负数下标 | -6 | -5 | -4 | -3 | -2 | -1 |
分片:list1 = [1, 3, 2, 9, 7, 8];
顺序排序:list1.sort()
逆序排序:list1.sort().reverse() 或者 list1.sort(reverse = True);
列表:一个大仓库,你可以随时往里边添加和删除任何东西;
元组:封闭的列表,一旦定义,就不可改变(不能添加、删除或修改)
tuple1 = (x**2 for x in range(10))
tuple1是一个生成器,用__next__()
方法调用
r是原始字符串操作符。
列表、元组、字符串统称为序列,共同点:
修改全局变量的值用global关键字;
在嵌套的函数中,内部函数想修改外部函数的局部变量,使用nonlocal关键字;
字典不支持一键多值。
fromkeys方法是直接创建一个新的字典,不要试图使用它来修改一个原有的字典,因为它会直接无情的用把整个字典给覆盖掉。
不可变集合:frozenset();
集合是无序的,不可用索引值索引;set1 = {1, 1.0}为{1.0},1和1.0在set里等值;
open()函数默认的打开模式是’rt’,即可读、文本的模式打开。
f.seek()定位的文件指针是按字节为单位进行计算的。
pickle的实质就是利用一些算法将你的数据对象存储成二进制文件,存储在磁盘上,当然也可以放在数据库或者通过网络传输到另一台计算机上。
封装 | 对外部隐藏对象的工作细节 |
---|---|
继承 | 子类自动共享父类之间数据和方法的机制 |
多态 | 可以对不同类的对象调用相同的方法,产生不同的结果 |
类的属性和方法定义应该尽可能的抽象,更符合面向对象的思维。
__init__()
方法__init__()
特殊方法不应当返回除了 None 以外的任何对象,只能返回None。
__init__() should return None
当子类定义了与父类相同的属性和方法时,会将父类属性或方法覆盖,子类对象调用的时候会调用到覆盖之后的新属性或方法,父类的仍然存在,只是子类对象’看不到’。
super()函数的超级之处在于你不需要明确的给出任何基类的名字,它会自动的帮你找出所有的基类以及对应的方法,由于你不用给出基类的名字,这就意味着你如果需要改变了类继承关系,你只要改变 class 语句里的父类即可,而不必在大量代码中去修改所有被继承的方法。
多重继承容易导致重复调用问题,程序应该可控,而不能受到继承关系影响。
issubclass(class, classinfo) 函数:判断一个类是否为另一个类的子类
isinstance(object, classinfo) 函数:判断对象 a 是否为 类 A 的实例对象
python修饰符:其实 Python 的修饰符就是一种优雅的封装,但要注意的是只可以在模块或类定义内对函数进行修饰,不允许修饰一个类,一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。
@something
def f():
print("I love FishC.com!")
# 相当于
def f():
print("I love FishC.com!")
f = something(f)
魔法方法总是被双下划线包围,例如__init__()
, __init__()
方法的返回值一定是None,不能是其它。当重写__init__()
方法时一定不能忘记。
__new__()
方法__new__()
是在一个对象实例化的时候所调用的第一个方法。它跟其他魔法方法不同,它的第一个参数不是 self 而是这个类(cls),而其他的参数会直接传递给 __init__()
方法的。
python基于序列的三大容器是列表、元组、和字符串。
迭代:迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。迭代器不是一个容器,是实现了__next__()
方法的对象。
迭代器性质决定没有办法回退,只能往前进行迭代。不能获取上一个值。
判断一个容器是否拥有iter()和next()方法来判断是否具有迭代功能。
对于无法随机访问的数据结构 set 而言,迭代器是唯一的访问元素的方式。
协同程序就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。Python 是通过生成器来实现类似于协同程序的概念:生成器可以暂时挂起函数,并保留函数的局部变量等数据,然后在再次调用它的时候,从上次暂停的位置继续执行下去。
生成器所能实现的任何操作都可以用迭代器来代替,因为生成器实际上就是基于迭代器实现的,生成器只是一个yield语句,内部自动创建__iter__()
和__next__()
方法。将一个函数改为生成器说白了就是将return
改为yield
。
生成器的最大作用是使得函数可以“保留现场”,当下一次执行该函数是从上一次结束的地方开始,而不是重头再来。
简单实现:不可改变,常量名全部大写。
class Const:
def __setattr__(self, name, value):
if name in self.__dict__:
raise TypeError('常量无法改变!')
if not name.isupper():
raise TypeError('常量名必须由大写字母组成!')
self.__dict__[name] = value
import sys
sys.modules[__name__] = Const()
sys.modules 是一个字典,它包含了从 Python 开始运行起,被导入的所有模块。键就是模块名,值就是模块对象。
import sys
sys.modules[__name__] = A();
python的包必须有一个__init__().py
文件,可以为空文件,但必须有。用来告诉python将该文件夹当成一个包处理。