参考文献:
https://www.liaoxuefeng.com
http://www.runoob.com
(1)数据类型
Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。Number类型也是对象,且是不可变对象。
常见的不可变对象:数字型量,string,tuple
另外,函数名也是变量,是指向函数的变量
特殊变量命名
__xxx__
这样的变量是特殊变量,可以被直接引用,但是有特殊用途_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用(但是也能引用到,但是不推荐)(2)列表切片、列表生成式
列表切片:取列表中的特定片段
列表生成式:把要生成的元素x * x放到前面,后面跟for循环。例如:[x * x for x in range(1, 11) if x % 2 == 0]
(3)生成器
动态生成元素,访问元素通过next函数进行访问。
g = (x * x for x in range(10))
next(g)
#或是通过循环:
for n in g:
print(n)
复杂的生成器:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b #每次执行到这里返回。再次执行时从上次返回的yield语句处继续执行
a, b = b, a + b
n = n + 1
return 'done' #执行到return,标识迭代结束,结束时,抛出StopIteration异常,可通过捕获异常,从异常中的value字段获取返回值
(4)关键字
yield
:用户生成器中;lambda
:即匿名函数,不用想给函数起什么名字finally
:异常处理is
:两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相not
:表示逻辑‘非’pass
:语句占位符函数可以同时返回多个值,但其实就是一个tuple
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
关于默认参数,需要注意:
(1) map
:Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
(2) reduce
: reduce() 函数会对参数序列中元素进行累积。
>>>def add(x, y) : # 两数相加
... return x + y
...
>>> reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
15
(3)filter
: 用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
def is_odd(n):
return n % 2 == 1
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)
(4) len
:获取序列长度
(5) max ,min
:返回序列中最大最小值
(6)callable(obj)
: 查看一个obj是不是可以像函数一样调用
(7)dir(obj)
:查看obj的name space中可见的name
(8)getattr(obj,name)
得到一个obj的name space中的一个name
(8)setattr(obj,name,value)
为一个obj的name space中的一个name指向vale这个object
(9)delattr(obj,name)
从obj的name space中删除一个name
type(obj) 查看一个obj的类型
(10)isinstance(obj,cls)
查看obj是不是cls的instance
(11)issubclass(subcls,supcls)
查看subcls是不是supcls的子类
(12)类型转化:chr, ord, oct, hex, str , list ,tuple, dict, int , float, long
(13)数学运算:divmod , pow, round
函数不仅可以返回普通值,还可以作为返回值。
如果在一个内部函数里对外部作用域(但不是全局作用域)的变量进行引用,内部函数称为闭包(closure)
>>> def lazy_calc_sum(num_list):
def calc_sum():
s = 0
for i in num_list:
s += i
return s
return calc_sum
在上面的例子中,我们在函数lazy_clac_sum中又定义了函数calc_sum,并且,内部函数calc_sum可以引用外部函数lazy_calc_sum的参数和局部变量,当lazy_calc_sum返回函数calc_sum时,相关参数和变量都保存在返回的函数中。
在使用闭关时,需要注意:由于内部函数没有执行,所以所引用的外部变量不会释放,还会保存。这个外部变量的修改会影响后续的调用执行情况(这些返回函数都引用这同一个外部变量)
例如:
def count():
fs = []
for i in range(1,4):
def g(a):
f = lambda : a*a
return f
fs.append(g(i))
return fs
f1,f2,f3 =count()
def count():
fs = [] #函数列表
for i in range(1, 4):
def f():
return i*i
fs.append(f) # 循环结束后,fs中存放了三个函数变量,这三个函数变量都引用了变量i。函数的执行是计算i*i。由于直接引用同一个变量,则执行结果都是一致的
return fs
f1, f2, f3 = count()
print( f1() )
print( f2() )
print( f3() )
因此,我们应尽量避免在闭包中引用循环变量,或者后续会发生变化的变量。
匿名函数类似与:lambda x : exp(x)
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
python 函数装饰器类似于Java中的标注。
from functools import wraps
def decorator_name(f):
# 调用functools.wraps修饰decorated函数,使得被修饰的函数能保持自己的__name__等信息。也
#可以不使用
@wraps(f)
def decorated(*args, **kwargs):
if not can_run:
return "Function will not run"
return f(*args, **kwargs)
return decorated
@decorator_name #使用装饰器修改func函数
def func():
return("Function is running")
can_run = True
print(func())
# Output: Function is running
can_run = False
print(func())
# Output: Function will not run
给函数常用的参数值设定为参数的默认值,可以降低函数调用的难度。偏函数也可以做到这一点。
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
Python 异常继承体系
https://blog.csdn.net/gaoxin12345679/article/details/47017483
完整的异常处理格式:
try:
XXXX #可能发生异常的语句
except
print("异常处理")
else
print('try内代码块没有异常则执行我')
finally:
print('无论异常与否,都会执行该模块,通常是进行清理工作')
主动抛出异常:
raise [Exception [, args [, traceback]]]
自定义异常
class XXException(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
https://www.cnblogs.com/kex1n/p/5977051.html
模块,在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。
模块属性__name__
,它的值由Python解释器设定。如果脚本文件是作为主程序调用,其值就设为__main__
,如果是作为模块被其他文件导入,它的值就是其文件名
。
模块可以导入其他的模块。通常将import语句放在模块的开头,被导入的模块名字放在导入它的模块的符号表中。
模块搜索路径
当导入一个模块时,解释器先在当前包中查找模块,若找不到,然后在内置的built-in模块中查找,找不到则按sys.path给定的路径找对应的模块文件(模块名.py)
sys.path的初始值来自于以下地方:
模块能像包含函数定义一样,可包含一些可执行语句。这些可执行语句通常用来进行模块的初始化工作。这些语句只在模块第一次被导入时被执行。这非常重要,有些人以为这些语句会多次导入多次执行,其实不然。
模块在被导入执行时,python解释器为加快程序的启动速度,会在与模块文件同一目录下生成.pyc文件。我们知道python是解释性的脚本语言,而.pyc是经过编译后的字节码,这一工作会自动完成,而无需程序员手动执行。
通常包总是一个目录,可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 __init__.py
。然后是一些模块文件和子目录,假如子目录中也有 __init__.py
那么它就是这个包的子包了。
在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,这里就需要运用包的概念了。包对应于文件夹,使用包的方式跟模块也类似,唯一需要注意的是,当文件夹当作包使用时,文件夹需要包含__init__.py
文件,主要是为了避免将文件夹名当作普通的字符串。__init__.py
的内容可以为空,一般用来进行包的某些初始化工作或者设置__all__
值,__all__
是在from package-name import *这语句使用的,全部导出定义过的模块。
python包是:
__init__.py
文件的目录,该目录下一定得有这个__init__.py
文件和其它模块或子包。定义方式:
class Student(object):#括号中的是父类,括号后面有一个分号
def __init__(self, name, score): # 类实例方法:和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self
self.name = name
self.score = score
类变量、类成员变量
class Member():
num=0 #类变量,可以直接用类调用,或用实例对象调用
def __init__(self,x,y):
self.x=x #实例变量(成员变量),需要它是在类的构造函数内以self.开头来定义的
(1)类实例变量:成员变量一定是以self.的形式给出的,因为self的含义就是代表实例对象;
(2)类变量:在类定义下直接声明定义的
特殊变量:
(1)__XX
:标识私有变量(private),只有内部可以访问,外部不能访问
(2)__XX__
:特殊变量,特殊变量是可以直接访问的
(3)__slots__
变量:限制该class实例能添加的属性,仅对当前类实例起作用,对继承的子类是不起作用的
类实例方法、类方法、静态方法
class Foo(object):
def test(self)://定义了实例方法 ,第一个参数必须是实例对象,该参数名一般约定为“self”
print("object")
@classmethod
def test2(clss)://定义了类方法,第一个参数必须是当前类对象,该参数名一般约定为“cls”
print("class")
@staticmethod
def test3()://定义了静态方法,参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法
print("static")
(1)类实例方法:默认的形式,只能由实例对象调用,第一个参数必须是实例对象,该参数名一般约定为“self”。只能由实例对象调用
(2)类方法:通过@classmethod
装饰器定义,第一个参数必须是当前类对象,该参数名一般约定为“cls”。实例对象和类对象都可以调用
(3)静态方法:通过@staticmethod
装饰器定义,参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法。实例对象和类对象都可以调用。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。
特殊方法
(1)__str__
(2)__iter__
(3)__getitem__
(4)__getattr__
(5)__call__
(6)__init__
关于元类
http://python.jobbole.com/88795/
类也是对象,名字就是类名。这个对象(类)自身拥有创建对象(类实例)的能力,而这就是为什么它是一个类的原因。但是,它的本质仍然是一个对象,于是你可以对它做如下的操作:
因为类也是对象,你可以在运行时动态的创建它们,就像其他任何对象一样。首先,你可以在函数中创建类,使用class关键字即可。
元类就是类的类。函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。现在你想知道那为什么type会全部采用小写形式而不是Type呢?好吧,我猜这是为了和str保持一致性,str是用来创建字符串对象的类,而int是用来创建整数对象的类。type就是创建类对象的类。你可以通过检查__class__
属性来看到这一点。Python中所有的东西,注意,我是指所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来。
(1)接口
python没有定义接口的关键字。定义接口只是一个人为规定,在编程过程自我约束。一般来说,以I开头的类视为接口。
class IOrderRepository:
def fetch_one_by(self,nid):
raise Exception('子类中必须实现该方法')
(2) 多继承
Python支持多继承
class C(A,B):
def __init__(self):
pass
注意:python中使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承,也叫菱形继承问题)等。
(3)关于抽象类与抽象方法:
抽象类是包含抽象方法的类,而抽象方法不包含任何可实现的代码,只能在其子类中实现抽象函数的代码。
定义抽象类与抽象方法:
从abc模块调用类abstractmethod和类ABCMeta,自己定义类Foo,继承抽象类ABCMeta,在类Foo中定义exec方法,并添加装饰器abcstractmethod。定义类A继承类Foo,并实例化对象obj,类A中必须有类Foo中的方法否则就会抛出异常。
from abc import abstractmethod,ABCMeta
class Foo(metaclass=ABCMeta):
@abcstractmethod
def exec(self):
pass
class A(Foo):
pass
obj=A()
或是通过指定元类:
import abc
class A(object):
__metaclass__ = abc.ABCMeta #指定元类
@abc.abstractmethod
def load(self, input):
return
@abc.abstractmethod
def save(self, output, data):
return
https://www.cnblogs.com/Commence/p/5587995.html
读写文件是最常见的IO操作。python内置了读写文件的函数。
读写文件就是请求操作系统打开一个文件对象通常称为文件描述符,然后,通过操作系统提供的借口从这个文件中读取数据,或者把数据写入这个文件对象
基本处理模式一:
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
但是每次都这么写实在太繁琐,
基本处理模式二:
with open('/path/to/file', 'r') as f:
print(f.read())
file-like Object
像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。
StringIO就是在内存中创建的file-like Object,常用作临时缓冲。