Python3基础复习
基本语法
基本语法只列举与Java不一样的。
运算符
and, or而非 &&, ||,另外还有not
/相当于java的double除法,**相当于java的Math.pow(a, b)
0、空字符串、列表、元组等都可以返回False
位运算符:~相当于java的
输出格式
print('%s%d%f'%(stringVar, intVar, floatVar), end = ' ')
数据类型
- str""
- 切片[起步:结束:步长]
- 常用函数:find不存在返回-1, index不存在会报错, count(str, start, end), replace(str1, str2, count), split, startswith, upper, ljust, center, partition, strip, join, isalnum(字母或数字), isalpha
- list[]
- 同样通过[index]取值,但没有切片
- 常用函数:append, insert, pop(index), remove(content), count, extend(集合), index, reverse, sort, clear, copy
- tuple():元素不可变
- 切片
- dict
- 对key赋值时如果没有该key就是添加
- 常用函数:get(key, default), keys(), values(), items()用于遍历dict,如
for k, v in dict1.items()
内置函数,类似static func:del()真的在内存中删去, in, not in, len, max字符串/列表都可以, list, tuple, type, id查内存位置, isinstance(var, varType)也可以 isinstance(var, (varType1, varType2)), abs, sorted(list, reverse), sum(list), round(float, digit), eval("str num expression")
集合可以解包赋值,即a,b,c = [1,2,3]
推导式
# list推导式,返回list
variable = [func(parm) for parm in iterableObj if parm == 2]
resList = [squared(i) for i in range(10) if i % 3 is 0]
# dict推导式
# 聚合
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {
k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
for k in mcase.keys()
if k.lower() in ['a','b']
}
# Output: {'a': 17, 'b': 34}
# 交换kv
mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
# tuple推导式
squared = {x**2 for x in [1, 1, 2]}
# Output: set([1, 4])
生成器的()方式很类似,详细看函数部分的生成器下面。
数据结构
list里面存储的实际上是指针。
拷贝:list、dict可变,另外三个不可变
浅拷贝:list2 = list1[:]或list1.copy(),只是新建了一个list存储新指针,但指针都是指向原来的对象。如果改变其中一个list的指针不会影响另外一个,即list[index] = xxx。但如果指针指向的对象被修改,两者都会受影响,即a = xx, list[a, ...], a[index] = xxx。
深拷贝:import copy,然后copy.deepcopy(),如果数据类型不可变,那指针仍指向原对象;如果可变,则会复制可变对象,指向新的可变对象。
函数
可变对象和不可变对象:可变对象作为参数时,传入的是本体。不可变对象作为参数时,传入的是副本。在函数里无法对函数外的指针进行重定向(除非用global,但最好不用),只能对传入的可变对象进行修改。
参数类型:位置参数、默认参数、关键字参数、可变参数
默认参数:def func(parm1, parm2=2):
默认参数放到右边
关键字参数:func(parm2=a, parm1=2)
实现参数顺序的变化,但关键字只能全写或者不写(除非设置默认参数)
可变参数(都是可选参数,即设置了可以不给):
-
def func(*args):
,调用func(a, b, c), func(a)
传入的参数会变为tuple,其指针为args。 -
def func(**kargs):
,调用func(a = 1, b = 2)
,参数作为两个kv传入kargs的dict中 -
反过来,
def func(a,b)
可以解包调用args=(1,2), func(*args)
,**kargs
一样可以。
混合使用:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应遵循)
# 简单来说,对于后面的可变参数,a,b...的输入会被归入*args,a=b的关键字参数会被归入**kargs
def func(name, age, sex=1, *args, **kargs):
print name, age, sex, args, kargs
# func('a', 25, 2, 'music', 'sport', class=2)
# a 25 1 ('music', 'sport') {'class'=2}
返回值:
返回可以结果可以是多个参数,会被包裹在tuple内。返回没有类型限制。
生成器/迭代器
含有yield的函数就不是一般的函数了,而是生成器。调用一次next就执行到yield时暂停(不调用不执行),再调用就在暂停处继续。如果跳出循环,不再遇到yield,那么next会报错。利用for i in iterableObject:
更方便,即便最后一次没有yield(执行函数剩余部分)也不会报错。生成器能避免一次性生成一个大的数据集。
其他写法
a = (x for x in range(10)) # 同样调用一次next(a)执行一次
a = [x for x in range(10)] # 一次性生成10个数的list
tmp = yield i #不能赋值,除非在函数外加上下面的send,但send之前需要调用过一次next。这样i会变为11,并能够赋值给tmp。send同样可以启动一次迭代。
a.send(11)
# 创建迭代对象。for a in b中,b需要是迭代对象,之前提到的集合都属于。
it = iter(list)
lambda
Java的lambda需要特定的函数才能使用。
s = lambda x: x*2
s(10) # 相当于x=10,然后10*2
# 其他形式
s = lambda : "xxx"
s = lambda x, y: x+y
# 三元运算,parm1, parm2: 成立的返回值 if 判断条件 else 不成立的返回值
s = lambda x, y: x if x > y else y
高级函数
new_list = map(lambda x:x*2, old_list) # 返回map对象,可遍历
new_list = map(lambda x, y:x*y, old_list1,old_list2)
new_list = filter(lambda x:x>2, old_list) # 返回filter对象
new_list = reduce(lambda x, y:x+y, old_list, Optional(initialVar)) # 需要from functools import reduce
阅读理解
sorted(dic.items(), key = lambda x:x[1], reverse=True) # 根据值排序
list1 = [{key1:val1, key2:val2},
{key1:val3, key2:val4}
]
sorted(list1, key = lambda x:x[key2], reverse=True) # 根据字典的某个key的值排序
面向对象
import datetime, re
DATE_PATTERN = re.compile('^\d+\-\d+\-\d+$')
def str_to_date(date):
if isinstance(date, datetime.date):
return date
elif isinstance(date,str) and DATE_PATTERN.match(date):
return datetime.date(*map(int, date.split('-')))
raise TypeError
class Person():
'''
doc
'''
# 相当于java的static成员变量
life = True
def __init__(self, name, birthday, age):
self.name = name
self.birthday = birthday
self.__age = age # 私有属性,通过实现getter来查看。但其实可以强制访问
@property
def birthday(self):
return self._birthday
@birthday.setter
def birthday(self, birthday):
self._birthday = str_to_date(birthday)
@property
def age(self):
return datetime.date.today() - self.birthday
def __str__(self):
return '%s,%s(%s)'%(self.name,self.birthday, self.age)
# 静态和类方法都可以通过类或实例调用,都不能够使用实例属性和方法。静态方法不需要参数,类方法至少有cls参数
@staticmethod
def func1():
do something # 用Person.类属性访问
@classmethod
def func2(cls):
do something # 用cls.类属性访问
person = Person('Xiao Ming','1980-10-1')
print(person)
person.birthday = '1981-1-2'
print(person)
person.birthday = datetime.date(1979,12,12)
print(person)
person.birthday = '123456' # raise TypeError
class chinese(Person):
def __init__(self, name, birthday, province):
super().__init__(name, food)
self.province = province
内置类方法
person.__dict__ # 将属性变为dict
person.__doc__ # 文档信息
# 一般从下面这条代码后才开始写运行的代码,相当于java的main方法。否则被import时会执行不必要的代码。因为__name__在其他py文件中被调用时就变为了调用py文件的名字了
if __name__ == '__main__':
多继承
class A():
def a():
print("A,a")
class B():
def a():
print("B,b")
class C(A,B):
def c():
print("C,c")
c = C
c.a # 会调用A的方法(多继承中从左到右找)
补充
异常
try:
do something
except exceptionName:
do something
except Exception:
do something
else: # 无错误
do something
finally:
do something
模块和包
模块
import time # 模块,相当一个文件夹。
time.sleep(5)
from time import sleep / *
sleep(5)
import pandas as pd
# 同一模块直接import pyname
import a.b # 导入统一模块下的a模块的b.py
from a import b # 同上
import sys
print(sys.path) # 查看模块搜索路径,第一个为当前
sys.path.append('..//') #添加上一层的相对路径,这样就可以import上一层的模块了
dir() # 查看当前模块有哪些变量、模块、函数等
dir(moduleName) # 查看模块
import imp
imp.reload(modelName)
包
目录中只包含一个叫__init__.py
的文件时才被认为是包
# __init__.py的内容
__all__ = ['pyname1', 'pyname2'] # 允许导入的模块
文件
# mode : r只读,不存在提示错误;w只写,create or overwrite;a追加;a+读写,光标移到末尾
with open(path, mode, encoding='utf-8') as file:
content = files.read(charNum) # readlines()
with open(path, mode, encoding='utf-8') as file:
content = files.write(strContent) # 只接受str,需手动换行write('\n')
import os
print(os.getcwd()) # 当前路径
os.listdir(path)
os.path.isfile(path) # exists(), split()将目录和文件分开列出
时间
import time
timeTuple = time.localtime(TimeStamp)
timestamp = time.mktime(TimeTuple)
timestamp = time.time()
formattedTime = time.strftime('%Y-%m-%d %H:%M:%S', timeTuple)
timeTuple = time.strptime(strTime, '%Y-%m-%d %H:%M:%S')
# 三天前时间戳
now_ts = time.time()
three_age_ts = now_ts - 60*60*24*3
线程和进程
python不支持真多线程
import threading
t1 = threading.Thread(target=funcName, args=(parms,)) # threading.Thread都是子线程
t1.start()
t1.join(timeout)
t1.setDaemon(True) # 主线程结束杀死子线程
# Lock
lock = threading.Lock
lock.acquire()
try:
do something
finally:
lock.release()
import multiprocessing
p1 = multiprocessing.Process(target=funcName, args=(parms,))
p = multiprocessing.Pool(num)
for i in range(5):
p.apply(func, args=(i,)) # 串行,线程一个一个创建
p.apply_async(func, args=(i,)) # 并行,线程一次性创建
p.close
参考: