1. 字符编码:
ASCII码:1个字符以一字节储存
Unicode码:字符通常2字节存储,非常偏僻的字4个字节,**示例如下 **
A 00000000 01000001
中 01001110 00101101
utf-8码:英文字符1字节,汉字通常3字节,偏僻字4-6字节
用记事本编辑时,从文件读取的utf-8字符被替换为Unicode字符到内存中,编辑完成时,保存的时候Unicode被转换为utf-8保存到文件
python的字符串:ord(),chr():字母与ASCII码数字互换
ord('A') #65
- Unicode码的表示:u‘…’
把u’…’ 转换为utf-8编码’…’ 用encode(‘utf-8’),反过来用decode(‘utf-8’)
保存源代码时,若源码包括中文,加上 #*_coding:utf-8_*
格式化显示:
类似于C:
'hello,%s'%'world' #hello,world
2.数据类型
dict:字典,查找速度快,不会因字典变大而变慢。实现这种特性的算法是哈希算法(hash)
set: 不重复,可通过remove()删元素
list:列表,通过pop()删元素
#python中,不可变对象永远不可变,如字符串
a='ABC'
b=a.replace('A','t') #b=''tBC' a='ABC'
cmp(x,y) #x<y return -1; x==y,return 0;x>y return 1
python数据类型转换:int() ,float() ,str() ,unicode() ,bool()
3.函数
函数名其实就是指向一个函数对象的引用,完全可以把函数赋给一个变量
空函数:
def nop():
pass
pass还可以用于其他语句:
if age >=18:
pass
python函数:默认参数在后,必选参数在前;默认参数必须指向不变对象(str,None)
args—–可变参数:以表示,表示传入参数个数可变,组装成tuple
kw——关键字参数:以表示,在函数调用时直接组装成dict
>>> kw = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **kw)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
递归函数:每调用一次,栈加一层栈帧,函数返回,栈减一层栈帧,易溢出
def fn(n):
if n==1:
return 1
return n*fn(n-1)
尾递归:函数返回时,调用自身,并且return语句不包含表达式
def fact(n):
return fact_iter(n,1)
def fact_iter(num,product):
if num==1:return product
return fact_iter(num-1,num*product)
但python编译器没有对尾递归做优化,故依然会栈溢出
3.高级特性
python迭代
形式:for key in d:
若d为dict,默认迭代key
for k,v in d.iteritems():
python 内置的enumerate可以把list变成索引-元素对
for i,value in enumerate(['A','B','C']):
列表生成式:
[x*x for xin range(1,11)]
[k+'='+v for k,v in d.iteritems()]
使用isinstance 可判断一个变量是否为字符串
生成器generator:
g=(x*x for x in range(10))
generator 保存的是算法,可以节省空间。
对于函数,若定义中包含yield关键字,那么该函数为生成器
>>> def odd():
... print 'step 1'
... yield 1
... print 'step 2'
... yield 3
... print 'step 3'
... yield 5
...
>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5
>>> o.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
4.高阶函数
map:将传入的函数依次作用到序列每个元素
reduce:
reduce(f,[1,b,c]) #f(f(a,b),c)
filter:把传入的函数依次作用于每个元素,实现筛选元素
def not_empty(s):
return s and s.strip()
filter(not_empty, ['A', '', 'B', None, 'C', ' '])
# 结果: ['A', 'B', 'C']
sorted函数:用于排序,默认从小到大
from operator import itemgetter
b=sorted(a,key=itemgetter(1)) #对value排序
b=sorted(a,reverse=1) #倒序
装饰器:decorator
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
@log
def now():
print '2013-12-25'
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print '2013-12-25'
>>> now = log('execute')(now)
由于装饰后的now()函数的name属性已经变成了 wrapper,所以,需要把原始函数的name等属性复制到wrapper()函数中,这时候可以利用到Python内置的functools.wraps
import functools
def log(func):
@functools.wraps(func) #在wrapper前面加上这一句
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
安装第三方模块:pip,easy_install
模块搜索路径:默认当前目录,但可以增添。搜索路径存放在sys模块的path变量中
import sys
print sys.path
sys.path.append('...') #增加搜索路径,但不是永久性有效
加路径的方法还有,设置环境变量PYTHON PATH,永久性的
future:使旧版python得到新版的某些特性
from _future_ import unicode_literals
from _future import division
5.python对象
class Student(object):
def __init__(self,name,score):
self.name=name
self.score=score
def print(self):
print '%s,%s'%(self.name,self.score)
双下划线开头的变量为私有变量,不可在外部访问
在Python中,变量名以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
多态:
在继承中出现,当父类与子类有相同的重名函数时出现。多态意味着,不同子类在运行重名函数时,总是会 调用自身的函数
获取对象信息:type,isinstance,dir—获取所有属性和方法
type(123),isinstance('a',str)
- __xxx__的属性和方法在python里有特殊用途,如
__len__返回长度。调用len()获取对象长度时,实际上len()内部是通过该对象的__len__()方法获取
len('ABC') # 'ABC'.__len__()
- getattr 获取属性
- setattr 设置属性
- hasattr 判断是否有属性
hasattr(obj,'x')
getattr(obj,'x')
setattr(obj,'x',19) #设置属性y,值为19
getattr(obj,'x',404) #获取属性x,不存在返回404
- 动态绑定属性和方法
>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student) #给Student类绑定set_score方法
- __slots__:限制class的属性,只对当前类有作用,子类不受限制
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
- @property能够将方法变为属性
class Student(object):
@property
def birth(self): #把一个getattr方法变为属性,有可读特性
return self._birth
@birth.setter #把setattr方法变为属性,可写特性
def birth(self, value):
self._birth = value
@property #把一个getattr方法变为属性,可读特性
def age(self):
return 2014 - self._birth
上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。
- 多重继承:一个子类继承自多个父类,称为Mixin
class Runnable(object):
def run(self):
print('Running...')
class Flyable(object):
def fly(self):
print('Flying...')
class Bat(Mammal, Flyable):
pass
Mixin的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个Mixin的功能,而不是设计多层次的复杂的继承关系。
定制类:__str__,__repr__,__getitem__,__getattr__,__call__
callabel()函数—–可判断一对象是否是可调用对象type—可以查看一个类或变量的类型,也可以创建出新的类型,这是python动态语言的特点—–函数或类的定义在运行时创建
>>> def fn(self, name='world'): # 先定义函数
... print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello)) #类的类型就是type
<type 'type'>
>>> print(type(h))
<class '__main__.Hello'>
这里type需要传入三个参数:
1.class的名称
2.继承的父类的集合,tuple形式
3.绑定方法hello和函数fn
- metaclass:控制类的创建行为,译为元类。先定义metaclass,然后创建类。比较复杂,具体我也没学会
6.错误处理
try:
print 'try...'
r = 10 / 0
print 'result:', r
except ZeroDivisionError, e: #e为错误内容
print 'except:', e
finally: #finally语句一定会被执行
print 'finally...'
print 'END'
- logging—打印出错误,并且让程序继续运行下去
# err.py
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except StandardError, e:
logging.exception(e)
main()
print 'END'
$ python err.py
ERROR:root:integer division or modulo by zero
Traceback (most recent call last):
File "err.py", line 12, in main
bar('0')
File "err.py", line 8, in bar
return foo(s) * 2
File "err.py", line 5, in foo
return 10 / int(s)
ZeroDivisionError: integer division or modulo by zero
END
- raise:抛出错误,抛出错误能抛出自己定义的,但默认抛出系统定义的
try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!') #抛出另外类型的错误(本来应该抛出ZeroDivisionError)
- 调试:
1.print语句
2.assert断言:
assert n!=0 'n is zero'
3.logging语句,打印出错误日记
# err.py
import logging
logging.basicConfig(level=logging.INFO) #指定允许记录信息的级别
s = '0'
n = int(s)
logging.info('n = %d' % n)
print 10 / n
$ python err.py
INFO:root:n = 0
Traceback (most recent call last):
File "err.py", line 8, in <module>
print 10 / n
ZeroDivisionError: integer division or modulo by zero
4.pdb调试
5.IDE调试