指定可执行程序运行python脚本:
#!/usr/bin/python
操作系统执行脚本时调用/usr/bin下的python解释器。
#!/usr/bin/env python
先到env设置里查找python的安装路径,再调用对应路径下的python解释器。防止没有将python装在默认(/usr/bin)路径。
添加命令让Python脚本像shell脚本一样可直接执行:./hello.py
1、加权限chmod +x hello.py
2、windows下的代码有时需要执行dos2unix命令
# -*- coding: utf-8 -*- 中文注释
系统自带的全局变量:
__doc__ 文件注释
__file__ 当前文件路径
__package__ 指定文件所在的包,用分割当前文件None
__cached__ 缓存当前文件None
__name__ 主文件__name__== "__main__" 否则,等于模块名
if __name__ == '__main__' 判断是否是在直接运行该.py文件
编码转换
字符串可以编码成字节包,字节包也可以解码成字符串。
decode解码:将其他编码的字符串转换成 Unicode 编码
encode编码:将Unicode编码转换成其他编码的字符串
str1.decode(‘gb2312’) 解码:表示将gb2312编码字符串转换成unicode编码
str2.encode(‘gb2312’) 编码:表示将unicode编码的字符串转换成gb2312编码
1. '永远'.encode('utf-8') ==> b'\xe6\xb0\xb8\xe8\xbf\x9c'
2. b'\xe6\xb0\xb8\xe8\xbf\x9c'.decode('utf-8') ==> '永远'
Python内部的字符串一般是Unicode编码。代码中字符串的默认编码与代码文件本身的编码是一致的。所以要做一些编码转换通常以Unicode作为中间编码进行转换的,即先将其他编码的字符串解码成Unicode,再从Unicode编码成另一种编码。
如果编码的字符串已经是Unicode编码,就不需进行decode解码转换,直接用encode就可以编码成所需的编码。
列表、元组、字典、集合
列表
list
一种有序的集合,可以添加和删除其中的元素;用索引来访问list中每一个位置的元素,索引从0开始;元素的数据类型也可以不同;
n = ['l','i']
n.append(123) #后追加,['l', 'i', 123]
n.count('l') #1,计算出现几次
n.extend([111,222]) #批量添加(参数是list),['l', 'i', 123, 111, 222]
n.index('i') #1,获取值的索引
n.insert(1, 'Jack') #插入,['l', 'Jack', 'i', 123, 111, 222]
n.pop() #删除最后一个,['l', 'Jack', 'i', 123, 111]
n.remove('i') #移除元素,['l', 'Jack', 123, 111]
n.reverse() #反转,[111, 123, 'Jack', 'l']
del n[0] #直接删除第几个元素,[123, 'Jack', 'l']
列表生成式
列表的一般生成:list(range(1, 11)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环
[x * x for x in range(1, 11)] ==> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
for循环后面还可以加上if判断,可以筛选出仅偶数的平方
[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']
元组
tuple
一种有序列表,一旦初始化就不能修改。适合进行遍历操作的运算,对数据写保护。
a = (1991, 2014, ‘physics’, ‘math’)
字典
dict
使用键/值(key-value)存储,查找速度快,dict内部存放的顺序和key放入的顺序没有关系。
和 list 比较,dict有以下几个特点:
1.查找和插入的速度极快,不会随着key的增加而变慢
2.需要占用大量的内存,内存浪费多。用空间来换取时间。
创建空字典:{}
tel = {'jack': 4098, 'space': 4139}
tel['good'] = 4127 #{'space': 4139, 'good': 4127, 'jack': 4098}
tel['jack'] #4098
集合
set
- 和dict类似,也是一组key的集合,但不存储value
- set可以看成数学意义上的无序和无重复元素的集合。
因此,两个set可以做数学意义上的交集(&)、并集(|)。
创建一个空集合:set()
a = set(‘abracadabra’) #{‘a’, ‘r’, ‘b’, ‘c’, ‘d’}
字符串
'r'是防止字符转义的,如果路径中出现'\t',不加r的话\t就会被转义,而加'r'之后'\t'就能保留原样。
s = r'\tt' print(s) #'\tt'
s = '\tt' print(s) #' t'
切片
slice (for sequence)
list = [1, 1.3, 'a']
list[1:2] #[1.3] #from 1 to 2, not include 2
list[:2] #[1, 1.3] #from start to 2, not include 2
list[1:] #[1.3, 'a'] #from 1 to last
list[:] #[1, 1.3, 'a'] #all == list[:None]
list[:10:2] #前10个数,每两个取一个
list[::5] #每5个取一个
字符串'xxx'也可以看成是一种list,每个元素就是一个字符。
字符串也可以用切片操作,操作结果仍是字符串:'ABCDEFG'[:3]) #ABC
index
(索引)
从左到右依次:0,1,2,…, n-1;
从右到左依次:-1,-2,…, -n;
list[0] = list[-n]
list[n-1] = list[-1]
==> list[len(list) - i] = list[-i]
list tuple dict 类型转换
tuple(seq) : 把一个sequence转换成一个tuple
tuple([1,2,3,4]) #(1, 2, 3, 4)
list(seq) : 把一个sequence转换成一个list
#tuple to string :''.join
#tuple not to dict
list((123, 'xyz', 'zara', 'abc')) #[123, 'xyz', 'zara', 'abc']"
eval(""{'name':'ljq','age':24}"") #{'name': 'ljq', 'age': 24}"
dict = {'name': 'Zara', 'age': '7', 'class': 'First'}
list(dict) #['name', 'class', 'age']"
list(dict.values()) #['Zara', 'First', '7']"
#join用来连接字符串
a="abcd"
",".join(a) #a,b,c,d
"|".join(['a','b','c']) #a|b|c
",".join(('a','b','c')) #a,b,c
#list to tuple :tuple()
#list to string:''.join
#list not to dict
tuple([1,2,3,4]) #(1, 2, 3, 4)
tuple({1:2,3:4}) #(1, 3) #for dict .return tuple for key
''.join(['1','2','3','4']) #"1234"
#tuple to list: list()
#tuple to string:''.join
#tuple not to dict
list((123, 'xyz', 'zara', 'abc')) #[123, 'xyz', 'zara', 'abc']
''.join(('1','2','3','4')) #"1234"
#string to list: list()
#string to tuple:tuple()
#string to dict
list("1234") #['1', '2', '3', '4']
tuple("1234") #('1', '2', '3', '4')
eval("{'name':'ljq','age':24}") #{'name': 'ljq', 'age': 24}
#dict to string
#dict to list
#dict to tuple
dict = {'name': 'Zara', 'age': '7', 'class': 'First'}
''.join(dict) #nameclassage
''.join(dict.values()) #ZaraFirst7
list(dict) #['name', 'class', 'age']
list(dict.values()) #['Zara', 'First', '7']
tuple(dict) #('name', 'class', 'age')
tuple(dict.values()) #('Zara', 'First', '7')
模块
一个功能的集合。一个包含所有定义的函数和变量的文件,后缀名是.py。
模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用python标准库的方法。
模块的种类:
1.内置模块(标准库,如os、file),在python安装时内置模块也随着安装。
2.自定义模块,自己写的模块。
3.第三方模块,python的使用不仅在于标准库,还有第三方库。
写代码之前先检查是否有标准库或者第三方库。使用第三方库,第一步要安装,在本地安装完就如同标准库一样使用。
模块的导入:
import xxx #import sys 导入sys模块下的全部模块
from xxx.xx import * #导入模块下的全部模块
from xxx import xx #导入模块下的指定模块导入fib模块内函数、变量的名称
//from fibo import fib
from xxx import xx as rename #导入指定模块 并设置别名
内置函数
不用import可以直接使用的函数。
input([prompt])
int("123") #123
str(123) #"123"
'ABC'.lower() #‘abc’ 字符串大写转小写
chr(i) 把一个ASCII数值变成一个字符
ord(i) 把一个字符或者unicode字符,变成ASCII数值
oct(x) 把整数x变成八进制表示的字符串
hex(x) 把整数x变成十六进制表示的字符串
float(x) 转换成一个浮点数
complex(x) 转换成复数
字符串转字节 bytes.fromhex(“01 02 03”) #b’\x01\x02\x03’
isinstance(x, str) 判断一个变量是不是字符串
lambda 匿名函数
sum2 = lambda x,y=10:x+y #print (sum2(2))
group() groups()
1.group() 同group(0)就是匹配正则表达式整体结果
2.group(1)列出第一个括号匹配部分,group(2)第二个括号匹配部分,group(3)第三个括号匹配部分
3.没有匹配成功的,re.search()返回None
re.search.groups() == (re.search.group(1), re.search.group(2), ...)
a = "123abc456"
print (re.search(""([0-9]*)([a-z]*)([0-9]*)"",a).group(0)) #123abc456,返回整体
print (re.search(""([0-9]*)([a-z]*)([0-9]*)"",a).group(1)) #123
print (re.search(""([0-9]*)([a-z]*)([0-9]*)"",a).group(2)) #abc
print (re.search(""([0-9]*)([a-z]*)([0-9]*)"",a).groups()) #('123', 'abc', '456')
range
print (list(range(1,5))) #代表从1到5(不包含5) [1, 2, 3, 4]
print (list(range(1,5,2))) #代表从1到5,间隔2(不包含5) [1, 3]
sorted 对list进行排序
1.数字,我们可以直接比较。对字符串排序,是按照ASCII的大小比较
sorted([36, 5, -12, 9, -21]) #[-21, -12, 5, 9, 36]
2.接收一个key函数来实现自定义的排序
sorted([36, 5, -12, 9, -21], key=abs) #[5, 9, -12, -21, 36]
map函数
接收两个参数(函数和序列),map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
def f(x):
return x * x
print (list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]))) #[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
reduce(f, [x1, x2, x3]) = f(f(x1, x2), x3)
def add(x, y):
return x + y
reduce(add, [1, 3, 5, 7]) #16
filter
接收一个函数和一个序列,把传入的函数依次作用于每个元素,然后根据返回值是True或False,
决定保留还是丢弃该元素。
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 3, 4]))# 结果: [1, 3]
文件操作
打开文件 open("filename", "r")
r只读 w写 rw读写 rb读二进制 wb写二进制 w+写追加
f.write("a") #f.write(str) 写一字符串
f.read() #全读出来 f.read(size) 表示从文件中读取size个字符
f.readline() #读一行,到文件结尾,返回空串
f.readlines() #读取全部,返回一个list. list每个元素表示一行,包含"\n"
f.tell() #返回当前文件读取位置
f.seek(off, where) #定位文件读写位置. off表示偏移量,正数向文件尾移动,负数表示向开头移动。
#where为0表示从开始算起,1表示从当前位置算,2表示从结尾算.
f.flush() 刷新缓存
字符串操作
#strip() 去掉开头和结尾的空格和回车
lstrip() rstrip()
str = " 12356789123456789 "
str1 = "1235678987654321"
str.strip() #"12356789123456789"
str.lstrip() #"12356789123456789 " str.rstrip() #" 12356789123456789"
str1.strip("12") #"356789876543"
str1.lstrip("12") #"35678987654321" str1.rstrip("12") #"12356789876543"
#split() split(str="",num = string.count(str))[n]
str = "www.doiido.com.cn"
str.split('.') #['www', 'doiido', 'com', 'cn']
str.split('.',0) #['www.doiido.com.cn']
str.split('.',1) #['www', 'doiido.com.cn']
str.split('.',2)[1] #"doiido" #split twice and return items 1
#replace(old, new, max)
str = "this is string example....wow!!! this is really string";
str.replace("is", "was") #thwas was string example....wow!!! thwas was really string
str.replace("is", "was", 3) #thwas was string example....wow!!! thwas is really string
#count(sub, start= 0,end=len(string)) The times of the substring in a string
str = "this is string example....wow!!!";
sub = "is";
str.count(sub) #2
#partition()
str = "http://www.w3cschool.cc/"
str.partition("://") #('http', '://', 'www.w3cschool.cc/')
#find(str, beg=0, end=len(string)) rfind ; 失败返回: -1
#index(str, beg=0, end=len(string)) rindex; 失败返回: "ValueError: substring not found"
str = "this is string example....wow!!!";
str.find("is"); #2
str.rfind("is"); #5
str.index("is"); #2
str.rindex("is"); #5
#startswith(str, beg=0,end=len(string))
str = "this is string example....wow!!!";
str.startswith("this") #"True"
异常 exception
import sys
import traceback
try:
x = int(input("enter the first number: "))
y = int(input("enter the second number: "))
print (x/y)
except:
f = open("log.txt", 'a')
traceback.print_exc(file=f)
f.flush()
f.close()
'''
except:
info = sys.exc_info()
print (info[0],":",info[1])
except Exception as e:
print (Exception, ":", e)
print ("the second number can't be zero!")
'''
打包 sdist
from distutils.core import setup
setup(
name='login', #这个是最终打包的文件名
version='1.0.0',
py_modules=['login'], #要打包哪些.py文件
)
#1. python setup.py sdist 打包命令
# (python setup.py bdist_wininst 命令创建一个exe安装文件)
# (python setup.py build :build everything needed to install)
#2.在当前目录下,会创建dist目录,里面有个文件名为log-1.0.0.tar.gz,这个就是可以分发的包。
# 使用者拿到这个包后,解压,到log-1.0.0目录下
# 执行:python setup.py install,log.py就会被拷贝到python类路径下,可以被导入使用。
装饰器
闭包函数
闭包中被内部函数引用的变量,不会因为外部函数结束而被释放,而是一直存在内存中,直到内部函数被调用结束。
因为作用域的原因,在函数外部无法拿到函数中的变量和内部函数。
闭包常用方式:通常使用函数中的变量时可将变量作为返回值返回。
同理,在使用内部函数时,也可将函数名作为返回值返回。
def func():
name = 'python'
def inner():
print(name)
return inner
f = func() # f = func() = inner
f() # f() = inner
装饰器
本质是一个函数,可以让其他函数在不需要做任何代码变动的前提下增加额外的功能。
参数:要装饰的函数名(非函数调用)
返回:装饰完的函数名(也非函数调用)
def use_logging(func):
def decorator():
print("%s is running" % func.__name__)
func()
return decorator
@use_logging
def bar():
print('i am bar')
bar();
bar是要装饰的函数,@use_logging相当于执行bar = use_logging(bar),为func函数装饰并返回。
带参数的装饰器:
import logging
def use_logging(level):
def decorator(func):
def wrapper(*args, **argv):
if level == "warn":
logging.warn("%s is running" % func.__name__)
elif level == "info":
logging.info("%s is running" % func.__name__)
func(*args)
return wrapper
return decorator
@use_logging(level="warn")
def foo(name='foo'):
print("i am %s" % name)
foo();
use_logging是允许带参数的装饰器。实际上是对原有装饰器的一个函数封装,并返回一个装饰器。
@use_logging(level="warn")等价于@decorator