python 基础
输入与输出
输入
- raw_input(“按下enter键退出其他任意键显示…\n”)
- raw_input(unicode(‘按下enter键退出其他任意键显示…\n’,‘utf-8’).encode(‘gbk’)) #解决docs命令行下中文乱码
- ps:英文 ASCII 中文 GB2312 日文 Shift_JIS 韩文 Euc-kr
统一之后编码Unicode
Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符
输出
- print() print(r’’) [ 引号中内容默认不转义 ]
- print (’’’ 多行内容’’’)[ 输出多行内容 ]
- print(r’’‘多行内容’’’)[默认不转义输出多行内容]
- format()[hi . %s,you have $%d % (‘ty’,10) ]
print(format("hi . %s,you have $%d " % ('ty',10))) # hi . ty,you have $10
占位符 | 替换内容 |
---|---|
%d | 整数 |
%f | 浮点数 |
%s | 字符串 |
%x | 十六进制整数 |
数据类型
Python有五个标准的数据类型
- 数字型包括整型,长整型,浮点型,复数型;
- 非数字型包括字符串,列表,元组和字典 ;
数据类型 | 写法 |
---|---|
Numbers(数字) | a=1 |
String(字符串) | str=‘hello world’ |
List(列表) | list=[‘hello’,2,3,4,‘world’] |
Tuple(元组) | tuple=(‘hello’,2,3,4,‘world’) 只读 |
Dictionary(字典) | dict = {1:‘this’, 2:‘is’, 3:‘dictionary’, 4:4} |
变量赋值 | 判断变量类型
- a = b = c =1 # 创建一个整形对象,值为1,三个变量被分配到相同的内存空间上
a,b,c=1,2,‘join’ # a=1 b=2 c=‘join’ - 判断变量类型 type(n)
type() 不会认为子类是一种父类类型。
isinstance() 会认为子类是一种父类类型。
算术运算符
- 算术运算符 ±*/ a**b a的b次幂 a%b 取余 a//b 取整除 - 返回商的整数部分
注意:Python2.x 里,整数除整数,只能得出整数。如果要得到小数部分,把其中一个数改成浮点数即可。
1/2=>0
1.0/2=>0.5
1/float(2)=>0.5 - Python位运算符 & | ^异或 ~ 取反 << 左移 高位丢弃,低位补零 >> 右移 低位丢弃,高位补零
a = 0011 1100
b = 0000 1101
(a ^ b) 输出结果 49 ,二进制解释: 0011 0001
a << 2 输出结果 240 ,二进制解释: 1111 0000
a >> 2 输出结果 15 ,二进制解释: 0000 1111
自定义函数
- 定义默认参数要牢记一点:默认参数必须指向不变对象!减少了由于修改数据导致的错误。可以多段代码调用同一个函数。
- 可变参数的书写
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
调用方式:calc([1,2,3]) *numbers表示把[1,2,3]这个list的所有元素作为可变参数传进去
- 关键字参数
可以传入任意个数的关键字参数,组合成dict返回来,也可以不传。person(name, age, **kw)
若只想传入city和job两个关键字参数,则写为 person(name, age, *, city, job),用 *分隔,不传这两个名称的参数会报错,关键字参数有默认值时可以不传。(感觉这样写个位置参数更好)
可变参数后跟关键字参数。person(name, age, *arg, city, job) 此时city, job为关键字参数。
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('tianyu', 25, relation='sister', hername='tianmi')
输出:
('name:', 'tianyu', 'age:', 25, 'other:', {'hername': 'tianmi', 'relation': 'sister'})
- 参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
def myfamily(name, age, boss="father", *secrect, **kw):
print('name:', name, 'age:', age, 'boss:',boss, 'secrect',secrect,'other:', kw)
me = ('tianyu', 25, 'mother', 'fight for you');
other = {'like':'make money'}
myfamily(*me, **other)
输出:
('name:', 'tianyu', 'age:', 25, 'boss:', 'mother', 'secrect', ('fight for you',), 'other:', {'like': 'make money'})
内置函数
定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
函数体内部可以用return随时返回函数结果;
函数执行完毕也没有return语句时,自动return None。
函数可以同时返回多个值,但其实就是一个tuple。
-
A
abs()–>取绝对值函数 -
B
-
C
-
D
del users[0]–>把第一个人踢出去 -
E
-
F
-
G
-
H
hex()–>把一个整数转换成十六进制表示的字符串
-
I
-
J
-
K
-
L
a = list (range(10)) / a = [0,1,2,3,4,5,6,7,8,9]
L[0:3] / L[-2:] –>切片函数 ,结果返回[0,1,2] / 返回[8,9]L[:4:2] / L[::2]–>前4个数,每两个取一个。返回[0,2] / 返回[0,2,4,6,8]
str = ‘abcdefg’;
str[:2]–>返回’ab’
touple = (0,1,2,3,4)
touple[:2]–>返回(0,1) -
M
max()–>返回最大值函数map(function_name, [list or tuple])–>高阶函数,类似于PHP的array_map
-
N
-
O
-
P
-
Q
-
R
reduce(function_name, [list or tuple])–>前两项做参数返回的值当做下次调用的第一个值,作用于序列上
users.remove(user)-> 在list型的人群里里删个人
from functools import reduce
def add(x, y):
return x + y
reduce(add, [1, 3, 5, 7, 9])
输出:25
- S
- T
- U
- V
- W
- X
- Y
- Z
for 循环 迭代 Iteration
- list、touple、string 循环写法
list = [1,2,3,4]
for i in list: //遍历1、2、3、4
for i,v in enumerate(list): // 遍历 key和value
dict = {'a': 1, 'b': 2, 'c': 3}
for i in dict: //默认遍历key
for v in dict.values(): //遍历value
for i,v in dict.items() : //遍历key与value
列表生成式 List Comprehensions
list(range(1,11))
输出:[1,2,3,4,5,6,7,8,9,10]
[x * x for x in range(1, 11)]
输出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[x * x for x in range(1, 11) if x % 2 == 0]
输出:[4, 16, 36, 64, 100]
[m + n for m in 'ABC' for n in 'XYZ']
输出:['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [x.lower() for x in L1 if isinstance(x, str)]
print L2
输出: ['hello', 'world', 'apple']
生成器 Generator
输出杨辉三角 详细代码click.
def triangles():
i,one=1,[1]
while i:
yield one
tran = [0]+one+[0]
lenght = len(tran)
one = [tran[x]+tran[x+1] for x in range(0,lenght-1)]
迭代器 Iterator
判断是否属于可迭代对象
from collections import Iterable
isinstance([], Iterable)
isinstance({}, Iterable)
isinstance('abc', Iterable)
isinstance((x for x in range(10)), Iterable)
可以被next()函数调用并返回下一个值的对象称为迭代器
生成器是Iterator对象,list、dict、str可迭代,但不是迭代器,可用iter()函数获得一个Iterator对象
函数式编程
高阶函数(类似于PHP array_map、array_reduce…)
map、reduce、filter、sorted
返回函数
# -*- coding:utf-8 -*-
def createCounter():
i=[0] #调用的时候这部分为什么没有被重新赋值
def counter():
i[0]+=1
return i[0]
return counter
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
print('测试通过!')
else:
print('测试失败!')
匿名函数
L = list(filter(lambda x:x%2, range(1, 20)))
print(L)
# 输出:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
lambda x:x*x
关键字 lambda冒号前面的x表示函数参数
装饰器
def log2(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
@log2('execute')
def now2():
print('test')
now2() #execute now2():
#test
print(now2.__name__) #now2
偏函数 partial
将某个函数的部分参数固定,返回新的名称的函数。
import functools
int2=functools.partial(int,base=2)
num = int2('100000')
print(num)
模块
方法名前有_、__的函数为私有函数
面向对象编程
声明对象 关键字为class+ 对象名称 +(继承的父类名称,无具体父类时,默认object)
class Student(object):
def __init__(self, name, score): #__int__方法(类中方法)第一个参数默认为self,
self.name = name
self.score = score
#调用时需:
Student('tianyu', 60) #self参数不用传,tianyu为name,60为score
获取对象信息
type(123) == int #True
type('abc') == str #true
判断一个对象是否是函数
import types
def fn():
pass
type(fn) == types.FunctionType #True
type(abs) == types.BuiltinFunctionType #True
type(lambda x:x) == types.LambdaType #True
type((x for x in range(10))) == types.GeneratorType #True
判断class类型,可以使用isinstance()函数,isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上,还可以判断一个变量是否属于某些类型中的一种
isinstance([1,2,3], (list, tuple)) #True
dir()可以获取变量的内在方法,以包含字符串的list形式返回
print(dir('abc'))
#['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', ...]
print(len('ABC')) #3
print( 'ABC'.__len__()) #3 #len()函数内部调用了__len__方法返回函数
是这样滴
class MyDog(object):
def __len__(self):
return 100
dog = MyDog()
print (len(dog))
配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态
class Person(object):
def __init__(self, name,age):
self.name = name
self.age = age
me = Person('tianyu', '25')
print(hasattr(me, 'name')) #True
print(hasattr(me, 'secret'))#False
print(getattr(me, 'age')) #25
print(getattr(me, 'secret', '404')) #404
setattr(me, 'secret', 'I love money')
print(getattr(me, 'secret', '404')) # I love money
面向对象高级编程
使用__slots__
给实例绑定一个属性
class Student(object):
pass
s = Student(object)
s.name = 'tianyu'
print(s.name) #tianyu
#绑定一个方法如下
def set_age(self, age):
self.age = age
from types import MethodType
s.set_age = MethodType(set_age, s)
s.set_age(25)
print(s.age) #25
__slots__ 限制类中可添加的属性
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
使用@property
# -*- coding:utf-8 -*-
class Screen(object):
@property # 将此方法变为属性
def width(self):
return self._width
@width.setter # @property又创建了一个@width.setter的装饰器
def width(self, value):
if not isinstance(value, int):
raise ValueError('width must be an integer!')
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self, value):
if not isinstance(value, int):
raise ValueError('height must be an integer!')
self._height = value
@property
def resolution(self):
return self._width * self._height
# 测试:
s = Screen()
s.width = 1024
s.height = 768
print('resolution =', s.resolution)
if s.resolution == 786432:
print('测试通过!')
else:
print('测试失败!')
多重继承 (php/ java单继承方式)
#比如,编写一个多进程模式的TCP服务,定义如下:
class MyTCPServer(TCPServer, ForkingMixIn):
pass
#编写一个多线程模式的UDP服务,定义如下:
class MyUDPServer(UDPServer, ThreadingMixIn):
pass
#如果你打算搞一个更先进的协程模型,可以编写一个CoroutineMixIn:
class MyTCPServer(TCPServer, CoroutineMixIn):
pass
#这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。
定制类
# -*- coding:utf-8 -*-
class Student(object):
def __init__(self, name):
self.name = name
print(dir(Student('tianyu')))
#['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__',
# '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
# '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
#'__weakref__', 'name']
print(Student('tianyu')) #<__main__.Student object at 0x000000000218C6D8>
print(Student('tianyu').__str__()) #<__main__.Student object at 0x000000000218C6D8>
print(Student('tianyu').__repr__()) #<__main__.Student object at 0x000000000218C7B8>
格式化输出需要重写__str__、__repr__
# -*- coding:utf-8 -*-
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__
print(Student('tianyu')) #Student object (name=tianyu)
print(dir(Student('tianyu')))
print(Student('tianyu').__str__()) #Student object (name=tianyu)
print(Student('tianyu').__repr__()) #Student object (name=tianyu)
如果一个类想被用于 for循环,必须实现一个__iter__()方法,该方法返回一个迭代对象,pyhton循环会调用改迭代对象的__next__()方法,拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
以斐波那契数列为例
# -*- coding:utf-8 -*-
class Fib(object):
def __init__(self):
self.a,self.b = 0, 1
def __iter__(self):
return self
def next(self): # pyhton 3.0 后此方法名为__next__
self.a,self.b = self.b, self.a + self.b
if self.a > 10 :
raise StopIteration()
return self.a
for n in Fib():
print(n) # 1,1,2,3,5,8
像list一样被调用,需增加__getitem__方法
# -*- coding:utf-8 -*-
class Fib(object):
def __getitem__(self, item):
if isinstance(item, int):
a, b = 1, 1
for x in range(item):
a, b = b, a+b
return a
if isinstance(item, slice):
start = item.start
stop = item.stop
if start is None:
start = 0
a, b = 1, 1
L=[]
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a+b
return L
f = Fib()
print f[0] #1
print f[0:5] #[1, 1, 2, 3, 5]
可以将对象看做dict,与__getitem__()对应的有__setitem__() 、__delitem__()
通过上面的方法可以把自己定义的类表现得和python自带的list、tuple、dict没什么区别
__getattr__
class Chain(object): #链式调用
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
__repr__ = __str__
print(Chain().status.ty.dipan) # /status/ty/dipan
__call__ 直接对实例进行调用, callable()函数判断一个变量是否可被调用
class Student(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('my name is %s' % self.name)
Student('tianyu')()
print(callable(Student)) # True
print(callable([1, 2, 3])) # False
枚举类
# -*- coding:utf-8 -*-
#python3.0 美美哒
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr'))
print(dir(Month))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
# 输出
# ['Apr', 'Feb', 'Jan', 'Mar', '__class__', '__doc__', '__members__', '__module__']
# Jan => Month.Jan , 1
# Feb => Month.Feb , 2
# Mar => Month.Mar , 3
# Apr => Month.Apr , 4
使用元类
type 可以查看变量信息,还可以创建对象
class Hello(object):
def hello(self, name='world'):
print ('Hello %s' % name)
h=Hello()
h.hello()
type写法
def sayhello(self, name='tianyu'):
print('Hello %s' % name)
Pro = type('Pro', (object,), dict(say=sayhello))
s = Pro()
s.say()
print(type(s)) #<class '__main__.Pro'>
metaclass 创建对象——待拓展
错误处理
try except finally 所有的错误类型都继承自BaseException
发生错误时 执行except语句,finally语句存在的话,无论什么情况必然会执行
try :
print('try...')
r = 10 / int('a')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
finally:
print('end...')
#输出:
#try...
#('ValueError:', ValueError("invalid literal for int() with base 10: 'a'",))
#end...
文件目录相关
文件处理
f = open( param1, param2, 【param3】, 【param4】 ) 函数
param1文件路径
param2 操作方式r/rb 读取普通文件/二进制文件 (图片、视频)
w/wb 写普通文件/二进制文件
a 以追加模式写入param3 指定编码 例:encoding=‘gbk’ 非必填
param4 编码不规范文档,忽略错误UnicodeDecodeError 例:errors=‘ignore’ 非必填
f.write(‘要写入的内容’)
f.read() 读取文件
f.close() 关闭文件
with open() with可自动调用文件的close方法
操作文件和目录
# coding:utf-8
import os
print(os.name) # nt windows系统 /posix 系统是Linux、Unix或Mac OS X
#print(os.uname()) #报错啦 在Windows上不提供此函数
print(os.environ) # たくさん 自己打印出来看
print(os.environ.get('SYSTEMROOT')) # C:\Windows
#文件目录操作
print(os.path.abspath('.')) # C:\Users\dell-3020\PycharmProjects\my0223\tool
print(os.path.abspath('..')) # C:\Users\dell-3020\PycharmProjects\my0223 感觉可以类推
print(os.path.splitext("os.py")) # ('os', '.py') 获取文件后缀
#创建目录
f = os.path.join('C:\Users\dell-3020', 'ty') #务必使用os.path.join函数拼接路径,其可以按系统正确输出路径
print(os.path.split(f)) # ('C:\\Users\\dell-3020', 'ty') 总是返回两部分,后一部分是最后级别的文件名或目录名
print(f) #C:\Users\dell-3020\ty
os.mkdir(f) # 创建成功 若文件已存在会报错
os.rmdir(f) # 删除成功
# os.rename(r'C:\Users\dell-3020\test.txt', r'C:\Users\dell-3020\test.py') # 文件重名名(r防止\转义) 若目录下此文件已存在报错
# os.remove(r'C:\Users\dell-3020\test.py') # 文件删除
# shutil模块提供了copyfile函数,看作是os模块的补充
#列出目录下的所有目录
print(os.listdir('C:\Users\dell-3020\PycharmProjects')) # 只返回目录下的目录名
print([x for x in os.listdir('.') if os.path.isdir(x)]) # 获取当前目录下所有目录
StringIO和BytesIO
序列化相关和json
序列化
# coding:utf-8
# dumps->loads dump->load
import pickle
d = dict(name='Bob', age=20, score=88)
d = {'name':'ty', 'age':'25'}
s = pickle.dumps(d)
print(s) # b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01X\x02\x00\x00\x0025q\x02X\x04\x00\x00\x00nameq\x03X\x02\x00\x00\x00tyq\x04u.'
me = pickle.loads(s)
print(me) #{'age': '25', 'name': 'ty'}
f = open(r'C:\Users\dell-3020\test.txt', 'wb') #文件不存在则创建
pickle.dump(s, f)
f.close() # 关闭之后才能以读取的方式打开
fr = open(r'C:\Users\dell-3020\test.txt', 'rb')
print(pickle.load(fr))
多进程与多线程
多进程
创建子进程
# coding:utf-8
from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
print('Run child process %s(%s)...' % (name, os.getpid()))
if __name__ == '__main__':
print('Parent process %s.' % os.getpid())
p = Process(target = run_proc, args=('test',)) #子进程执行函数run_proc 子进程名字test 创建子进程
print('Child process will start.')
p.start() # 启动子进程
p.join() # 方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
print('child process end')
批量创建子进程
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')