数据类型(也是对象来的)
整数(0xffe3)、浮点数(1.23e5==1.23*10的5次方)、字符串、True和False(使用and、or、not运算)、None(不等于0)
注意:没有常量(python把全大写变量定义为常量)
数据结构
- tuple
(v1,v2,v3)或者v1,v2,v3
- list
[v1,v2,v3],list[index],len(list) == 3,元素多了就慢但内存少
- dict
{k1:v1,k2:v2},dict[k1] == v1,if k1 in dict,k1和k2可以不同类型,快但内存多
- set
set([k1,k2,k3]),元素是dict的key,所以不重复且不可变对象
注意:运算符&交集,|并集
高级特性
- 切片
list[-2:]
- 迭代key:
for key in dict
- 迭代字符串:
for 变量 in 'ABC'
- 列表生成式:
[x * x for x in range(1, 11) if x % 2 == 0],[m + n for m in 'ABC' for n in 'XYZ']
- generator
next(),(x * x for x in range(10)),不占用空间,函数中yield v1到yield vn,可for,send(value)就是给(yield v)赋值,但启动generator时只能使用send(None),此时相当与next()。
注意:可for为Iterable,可next为Iterator,iter(Iterable) == Iterator
函数
-
高阶函数
# 高阶函数:以函数作为参数 def add(x, y, f): return f(x) + f(y) # map() def f(x): return x * x r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # list(list(r)) == [1, 4, 9, 16, 25, 36, 49, 64, 81] # type(r) == map,未解?map函数居然是一个class #reduce() def add(x, y): return x + y reduce(add, [1, 3, 5, 7, 9]) # 结果:25 #filter def is_odd(n): return n % 2 == 1 list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])) # 结果: [1, 5, 9, 15] #sorted sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) # 结果:['Zoo', 'Credit', 'bob', 'about'] # 加条件:key=func # 反向排序:reverse=True
-
闭包
引用作用域以外的变量
-
装饰器
def deco(function): # 由外到内调用 print("输出结果:") # 外 def _deco(string): print("before") # 内 function(string) print("before") return _deco @deco def p(arg): print(arg) p("hello") # 相当于deco(p)("hello"),而不是deco(p("hello")) # 输出结果: # before # hello # before
注:函数作为参数时不要带参数,带参数表示调用
-
偏函数
带有默认参数(key-value)的函数
int('110', base=2) # 二进制数“10”转十进制输出 #结果:6 def int2(x, base=2): return int(x, base) #相当于:int2 = functools.partial(int, base=2)
面向对象
-
只有对象里头的才叫method,其余的都叫function
-
私有方法
_xxx or __xxx,区别_xxx仍可访问,__xxx解释成_ClassName__xxx
注:obj.__xxx可赋值,但get_xxx()针对的是_ClassName__xxx,而不是__xxx
-
类属性与实例属性
- 类属性直接定义,不通过self.xxx定义
- 访问实例属性时,先找实例属性,没有时再找类属性
-
给类或对象绑定方法
带有self的外部方法set_name(self,name)
- 实例方法:obj.set_name = MethodType(set_name, Obj),仅对单个实例有效
- 类方法:ClassName.set_name = set_name
注:obj.method = MethodType(method,Obj)与Obj.method = MethodType(method,Obj)不同,Obj.method相当于java静态
-
type还可以动态创建类:
def func(self, name):
print(name)
# type([class_name],[父类tuple],[键值对:{[类的函数名]:[已定义好的函数名]}])
h = type('Hello', (object,), {"hello": func})
h().hello("Mike")
# 输出结果:Mike
- __slots__
class xxx(object): __slots__ = ("name","age") # 那么该类只允许name和age属性 # 注:其子类不受限制
- @property
class Student(object): # 设置可读属性 @property # @property相当于一个getter,并生成birth装饰器 def birth(self): return self._birth # 设置可写属性 @birth.setter def birth(self, value): self._birth = value @property def age(self): return 2017 - self._birth stu = Student() stu.birth = 1993 print(stu.age) # 结果:24
- Python支持多继承class class_name(Obj1,Obj2)(这点和Java单继承不同)
- __iter__(注:通常与next()、StopInteration()配套使用)
# __iter__()方法返回一个迭代对象, # 然后,Python的for循环就会不断调用该迭代对象的__next__()方法, # 拿到循环的下一个值,直到遇到StopIteration错误时退出循环 class Fib(object): def __init__(self): self.a, self.b = 0, 1 def __iter__(self): return self # 实例本身就是迭代对象,故返回自己 def __next__(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 100000: # 退出循环的条件 raise StopIteration() return self.a # 返回下一个值 for num in Fib(): print(num) # 结果输出:1 1 2 3 5 ... 46368 75025
- 枚举类
# @unique装饰器可以帮助我们检查保证没有重复值 @unique class Weekday(Enum): Sun = 0 # Sun的value被设定为0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6
Exception
- 如何知道程序出问题?
使用raise Err来抛出异常
(注:所有Err都是BaseException的子类,raise也可不加Err) - 抛出错误后如何处理?
通过try:...except:...finally:...
多进程与多线程
- 多进程
方式一:使用os.fork(),注:windows无法调用fork()
print('Process-%s start...' % os.getpid())
pid = os.fork() # 之后的代码分别在当前进程和子进程中执行
if pid == 0: # 返回0是子进程,父进程返回子进程id
print('I am child process (%s) and my parent is %s.'
% (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s)' % (os.getpid(), pid))
方式二:使用Process(target=[function],args=[tuple_args])
def run_in_child_process(name):
if isinstance(name, (str,)):
print("child process %s is running!" % name)
else:
raise TypeError("Name should be str type!")
child_process_name = 'thread_demo'
p = Process(target=run_in_child_process, args= (child_process_name,), name=child_process_name)
print('process %s will start!' % p.name)
p.start()
p.join()
print('process %s is end!' % p.name)
方式三:启动大量子进程使用pool.apply_async([function],args=[tuple_args])
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) # 这里设置同时执行的进程数量为4,默认为cpu核数
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join() # 调用join之前必须close
print('All subprocesses done.')
- 多进程与多线程的区别:
多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享 - 线程锁Lock
balance = 0
def change_it(n):
# 先存后取,结果应该为0:
global balance
balance = balance + n
balance = balance - n
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
补充
-
顺序赋值
a, b = v1, v2 (or a, b = Iterable)
注:Iterable的长度和变量个数一致 -
匿名函数:lambda
lambda x,y:(x+1)*y 相当于 def func(x,y): return (x+1)*y
-
*args is a tuple, **kwargs is a dict
- 注:tuple变量作为参数传入时也需要加星号,否则会被当作一个Integer传入
-
dir(obj):列出对象信息
-
Object、int等等都是type类型
-
全局变量
- 函数中引用外部变量完全没问题;
- 局部变量与全局变量同名是可以的,局部变量的修改不影响全局变量;
- 函数中可以使用global声明来定义全局变量。
-
字节与字符串互转
bytes object
b = b"example"
str object
s = "example"
str to bytes
bytes(s, encoding = "utf8")
bytes to str
str(b, encoding = "utf-8")
an alternative method
str to bytes
str.encode(s)
bytes to str
bytes.decode(b)
另外,拼接字符串可以使用str.join(str_list)
网友评论