目录php
人生苦短....哈哈,本身想吧!!! emmm。。。来真的 python语言的简洁、优美!
官网、网上视频、学习网站
一、python代码,简介,明确,优雅,简单易懂 二、开发效率高 三、可扩展性强
解释型:在执行程序时,计算机才一条一条的将代码解释成机器语言给计算机来执行 编译型:是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样计算机运行该程序时能够直接以机器语言来运行此程序,运行速度很快。
Cpython,IPython,Jpython,pypy,Ironpython Python是一门解释器语言,代码想运行,必须经过解释器执行,Python存在多种解释器,分别基于不一样语言开发,每一个解释器有不一样的特色,但都能正常运行Python代码,如下是经常使用的五种Python解释器: CPython:当 从Python官方网站下载并安装好Python2.7后,就直接得到了一个官方版本的解 释器:Cpython,这个解释器是用C语言开发的,因此叫 CPython,在命名行下运行python, 就是启动CPython解释器,CPython是使用最广的Python解释器。 IPython:IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方 式上有所加强,可是执行Python代码的功能和CPython是彻底同样的,比如不少国产浏览器 虽然外观不一样,但内核实际上是调用了IE。 PyPy:PyPy是另外一个Python解释器,它的目标是执行速度,PyPy采用JIT技术, 对Python代进行动态编译,因此能够显著提升 Python代码的执行速度。 Jython:Jython是运行在Java平台上的Python解释器,能够直接把Python代码编译成Java字节码执行。 IronPython:IronPython和Jython相似,只不过IronPython是运行在微软.Net平台上的Python解释器, 能够直接把Python代码编译成.Net的字节码。 在Python的解释器中,使用普遍的是CPython,对于Python的编译,除了能够采用以上解释器 进行编译外,技术高超的开发者还能够按照本身的需求自行编写Python解释器来执行Python代码,十分的方便!
一个字节=8位
1B(字节) = 8b(位) 1KB = 1024B 1MB = 1024KB 1GB = 1024MB
一、缩进:每一级4个缩进。连续跨行应该使用圆括号或大括号或者使用悬挂缩进。 二、代码长度约束 一行列数:PEP8 规定最大为79列,若是拼接url很容易超限 一个函数:不能够超过30行;直观来说就是完整显示一个函数一个屏幕就够了,不须要上下拖动 一个类:不要超过200行代码,不要超过10个方法 一个模块:不要超过500行 三、import 不要在一句import中引用多个库 四、命名规范 五、注释 整体原则,错误的注释不如没有注释。因此当一段代码发生变化时,第一件事就是要修改注释!
二进制转换成十进制:v = “0b1111011” print(int('0b1111011', 2)) 十进制转换成二进制:v = 18 print(bin(18)) 八进制转换成十进制:v = “011” print(int('011', 8)) 十进制转换成八进制:v = 30 print(oct(30)) 十六进制转换成十进制:v = “0x12” print(int('0x12', 16)) 十进制转换成十六进制:v = 87 print(hex(87))
如 10.3.9.12 转换规则为: 10 00001010 3 00000011 9 00001001 12 00001100 再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ? 答案: def func(x): lis = x.strip().split('.') li = [bin(int(i)) for i in lis] li2 = [i.replace('0b',(10-len(i))*'0') for i in li] return int(''.join(li2),2) ret = func('10.3.9.12') print(ret)
通常计算机默认的最大递归深度在1000左右,python最大递归深度通常在4000左右,跟计算 机的性能有关系,这个数不是一个定数,可经过一下方式测试 import sys print(sys.getrecursionlimit()) print(sys.setrecursionlimit(10000))
v1 = 1 or 3 -------------->1 v2 = 1 and 3-------------->3 v3 = 0 and 2 and 1-------->0 v4 = 0 and 2 or 1--------->1 v5 = 0 and 2 or 1 or 4---->1 v6 = 0 or Flase and 1----->False
ASCII码:使用一个字节编码,因此它的范围基本是只有英文字母、数字和一些特殊符号` `,只有256个字符。 Unicode:可以表示全世界全部的字节 GBK:是只用来编码汉字的,GBK全称《汉字内码扩展规范》,使用双字节编码。 UTF-8:是一种针对Unicode的可变长度字符编码,又称万国码。
机器码:是电脑CPU直接读取运行的机器指令,运行速度最快,可是很是晦涩难懂 字节码:是一种中间状态(中间码)的二进制代码(文件)。须要直译器转译后才能成为机器码。
规则:为真时的结果 if 断定条件 else 为假时的结果 应用场景:在赋值变量的时候,能够直接加判断,而后赋值
一、默认编码:2-->ascii,3-->utf-8 二、print的区别:python2中print是一个语句,不论想输出什么,直接放到print关键字后面便可。python3里,print()是一个函数, 像其余函数同样,print()须要你将要输出的东西做为参数传给它。 三、input的区别: python2有两个全局函数,用在命令行请求用户输入。第一个叫input(),它等待用户输入一个python表达式(而后返回结果)。 第二个叫作raw_input(),用户输入什么他就返回什么。python3 经过input替代了他们。 四、字符串:python2中有两种字符串类型:Unicode字符串和非Unicode字符串。Python3中只有一种类型:Unicode字符串。 五、xrange() python2里,有两种方法得到必定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器。 python3 里,range()返回迭代器,xrange()再也不存在。 更多不一样:https://www.cnblogs.com/weikunzz/p/6857971.html
a = 1 b = 2 答案:a = 1 b = 2 a,b = b,a
python2有非浮点数准备的int和long类型。int类型最大值不能超过sys.maxint,并且这个最大值是平台相关的。` 能够经过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在python3里,` 只有一种整数类型int,大多数状况下,和python2中的长整型相似。
python2里,有两种方法得到必定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器。 python3 里,range()返回迭代器,xrange()再也不存在。
readlines返回一个list,xreadlines方法返回一个生成器
0, [] , () , {} , '' , False , None
字符串:repleace,strip,split,reverse,upper,lower,join..... 列表:append,pop,insert,remove,sort,count,index..... 元组:index,count,__len__(),__dir__()` 字典:get,keys,values,pop,popitems,clear,update,items.....
表达式格式:lambda后面跟一个或多个参数,紧跟一个冒号,之后是一个表达式。冒号前是参数,冒号后是返回值。例如:lambda x : 2x 应用场景:常常与一些内置函数相结合使用,好比说map(),filter(),sorted(),reduce()等
一、空语句 do nothing 二、保证格式完整 三、保证语义完整
万能参数,解决了函数参数不固定的问题 *arg:会把位置参数转化为tuple` **kwarg:会把关键字参数转化为dict
is:判断内存地址是否相等 ==:判断数值是否相等
copy():浅copy,浅拷贝指仅仅拷贝数据集合的第一层数据 deepcopy():深copy,深拷贝指拷贝数据集合的全部层
python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收、分代回收)两种机制为辅的策略 计数机制 Python的GC模块主要运用了引用计数来跟踪和回收垃圾。在引用计数的基础上,还能够经过“标记-清除” 解决容器对象可能产生的循环引用的问题。经过分代回收以空间换取时间进一步提升垃圾回收的效率。 标记-清除: 标记-清除的出现打破了循环引用,也就是它只关注那些可能会产生循环引用的对象 缺点:该机制所带来的额外操做和须要回收的内存块成正比。 隔代回收 原理:将系统中的全部内存块根据其存活时间划分为不一样的集合,每个集合就成为一个“代”, 垃圾收集的频率随着“代”的存活时间的增大而减少。也就是说,活得越长的对象,就越不多是垃圾, 就应该减小对它的垃圾收集频率。那么如何来衡量这个存活时间:一般是利用几回垃圾收集动做来衡量, 若是一个对象通过的垃圾收集次数越多,能够得出:该对象存活时间就越长。
不可变类型(数字、字符串、元组、不可变集合) 可变类型(列表、字典、可变集合)
v = dict.fromkeys(['k1','k2'],[]) v['k1'].append(666) print(v) v['k1'] = 777 print(v) 答案:{'k1':[666],'k2':[666]} {'k1':777,'k2':[666]} 解析:formkeys()默认参数为可变数据类型时有
def num(): return [lambda x: i * x for i in range(4)] print([m(2) for m in num()]) 答案:[6, 6, 6, 6] 解析: 问题的本质在与python中的属性查找规则,LEGB(local,enclousing,global,bulitin), 在上面的例子中,i就是在闭包做用域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询获得的 因此:[lambda x: i * x for i in range(4)] 打印出来是含有四个内存地址的列表,每一个内存地址中的i 在在本内存中都没有被定义,而是经过闭包做用域中的i值,当for循环执行结束后,i的值等于3,因此 再执行[m(2) for m in num()]时,每一个内存地址中的i值等于3,当x等于2时,打印出来的结果都是6, 从而获得结果[6, 6, 6, 6]。
map,filter,zip,len,bin,oct,hex,int,float,bool,sum,min,max,str,list,tuple,dict,range,next,hash,help,id.....
filter(function,iterable)过滤函数 map(function,iterable)循环函数 reduce(function, iterable)累积函数
lis = ['%s*%s=%s'%(i,j,i*j) for i in range(1,10) for j in range(i,10)]
pip3 imstall 模块名 django,Matplotlib,Tornado,PyGame
os,sys,time,random,re,hashlib,logging,json,pickle....
match:从字符串的开头位置匹配,必须以此为开头 search:从开头开始查,找到符合的就返回结果
正则表达式通常趋向于最大长度匹配
a. [ i % 2 for i in range(10) ] ===>[0,1,0,1,0,1,0,1,0,1] b. ( i % 2 for i in range(10) )===>返回一个生成器的内存地址
a. 1 or 2 =========>1 b. 1 and 2 ========>2 c. 1 < (2==2)======>false d. 1 < 2 == 2======>ture
def func(a,b=[]): b.append(a) print(b) 函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list, 第二次执行仍是用第一次执行的时候实例化的地址存储,之后每次实例化都是
a = "1,2,3" li = a.split(',')
li = ['1','2','3'] lis = list(map(lambda x:int(x) li))
a = [1,2,3]正常的列表 b = [(1),(2),(3)] 虽然列表的每一个元素加上了括号,可是当括号内只有一个元素而且没有逗号时,其数据类型是元素自己的数据类型 b = [(1,),(2,),(3,)]列表中的元素类型都是元组类型
li = [x*x for x in range(1,11)]
li = [1, 1, 1, 23, 3, 4, 4] new_li = list(set(li)) new_li.sort(key=li.index)
使用python的内置语法 globals 全局变量
logging模块的做用: 一、程序调试 二、了解软件程序运行状况,是否正常 三、软件程序运行故障分析与问题定位 应用场景:网站的运维工做,程序实时监控
def Stack(object): def __init__(self): self.stack = [] def push(self,value): # 进栈 self.stack.append(value) def pop(self): # 出栈 if self.stack: self.stack.pop() else: raise LookupError('stack is empty!') def is_empty(self): # 查看stack是否为空 reture bool(self.stack) def top(self): # 取出stack中最新的值 return self.stack[-1]
一、%s %d 二、format格式化输出 三、print(f'内容{变量名}')
生成器:在 Python 中,一边循环一边计算的机制,称为 生成器(generator), 经过next()取值,两种表现形式一、将列表生成式的[]改成()二、含有yield关键字的函数 应用场景:优化代码,节省内存 迭代器:是访问集合元素的一种方式。迭代器同时实现了__iter__和__next__方法 可迭代对象:只要实现了__iter__方法的对象就是可迭代对象
lis = [0, 1, 3, 4, 5, 6, 7, 9, 10, 11,12,16,17] def binary_search(li, val): low = 0 high = len(li)-1 while low <= high: mid = (low + high) // 2 if li[mid] < val: low = mid + 1 elif li[mid] > val: high = mid - 1 else: return mid return None
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,而且外函数的返回值是内函数的引用。这样就构成了一个闭包。 通常状况下,在咱们认知当中,若是一个函数结束,函数的内部全部东西都会释放掉,还给内存,局部变量都会消失。 可是闭包是一种特殊状况,若是外函数在结束的时候发现有本身的临时变量未来会在内部函数中用到,就把这个临时变量绑定给了内部函数,而后本身再结束。
os模块负责程序与操做系统的交互,提供了访问操做系统底层的接口; sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
import random def rdm(n): lis = [] for i in range(n): n = random.randint(1,9) lis.append(str(n)) s = ''.join(lis) return int(s)
import os os.remove(r'path')
面向对象的程序设计的核心是对象(上帝式思惟),要理解对象为什么物,必须把本身当成上帝,上帝眼里世间存在的万物皆为对象, 不存在的也能够创造出来。对象是特征和技能的结合,其中特征和技能分别对应对象的数据属性和方法属性。 优势是:解决了程序的扩展性。对某一个对象单独修改,会马上反映到整个体系中,如对游戏中一我的物参数的特征和技能修改都很容易。 缺点:可控性差,没法向面向过程的程序设计流水线式的能够很精准的预测问题的处理流程与结果, 面向对象的程序一旦开始就由对象之间的交互解决问题,即使是上帝也没法预测最终结果。 应用场景:需求常常变化的软件,通常需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地
1:在继承中基类的构造(__init__()方法)不会被自动调用,它须要在其派生类的构造中亲自专门调用。 2:在调用基类的方法时,须要加上基类的类名前缀,且须要带上self参数变量。 区别于在类中调用普通函数时并不须要带上self参数 3:Python老是首先查找对应类型的方法,若是它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。 (先在本类中查找调用的方法,找不到才去基类中找)。
Python的类能够继承多个类,那么其寻找类方法的方式有两种: 当类是经典类时(主要在python2版本中的没有主动继承object的类),多继承状况下,会按照深度优先方式查找 当类是新式类时(python3版本中的全部类和python2中主动继承object的类),多继承状况下,会按照广度优先方式查找 简单点说就是:经典类是纵向查找,新式类是横向查找
一、super在面向对象继承类中代指父类,书写方法super(类名,self).属性或者方法或super().属性或者方法 二、super方法能够增长类之间调用的灵活性,当父类名发生变化时没必要修改 三、super方法在类的多继承时能够简化代码,避免代码冗余 四、super机制里能够保证公共父类仅被执行一次,执行的顺序遵循MRO,广度优先查询方法
functools用于高阶函数:指那些做用于函数或者返回其余函数的函数。一般状况下,只要是 能够被当作函数调用的对象就是这个模块的目标。
__new__:构造方法,建立一个对象,实例化时第一个被执行,返回一个建立好的对象及__init__(self)的self, 只有继承了object的类才会有这个方法 __init__:初始化方法,__init__在__new__的基础上完成一些其它初始化的动做,__init__没有返回值
函数和方法都封装了一些独立的功能,若是在类中定义的函数那就是方法(对象或者类名点方法名调用),不然就是函数(函数名()直接调用)
静态方法:是既不是用类中的属性又不使用对象中的属性,由类或者对象调用的方法,依赖python装饰器@staticmethod来实现 类方法:只使用类中的静态变量,通常都是由类调用,依赖python装饰器@classmethod来实现
__call__:对象的构造方法,对象加上(),能够触发这个类的__call__方法。 __len__:内置函数的len函数是依赖类中的__len__方法 __eq__:判断值是否相等的时候依赖__eq__方法 __hash__:判断hash值是否相等的时候依赖__hash__方法(拓展:set的去重机制其实就是根据__hash__和__eq__方法实现的) __str__:和str() print() %s 都是息息相关的,返回值必定是字符串类型 __repr__:和 repr() %r都是息息相关的,在没有__str__方法时,__repr__能够彻底取代__str__。 __del__ 析构方法,对应着一个对象的删除以前执行的内容
count = 0 for i in range(1,6): for j in range(1,6): for k in range(1,6): if (i != j) and (i != k) and (j != k): count += 1 if count % 6: print(f'{i}{j}{k}', end='|') else: print(f'{i}{j}{k}') print(count)
定义:经过用字符串数据类型的变量名来访问这个变量的值,在python面向对象中的反射,经过字符串的形式操做对象相关的属性或方法. 应用场景:用于处理经过用户输入,文件读取,或者网络传输所获得的字符串形式的指令来完成对应的操做
metaclass,直译为元类,简单的解释就是:当咱们定义了类之后,就能够根据这个类建立出实例, 因此:先定义类,而后建立实例。可是若是咱们想建立出类呢?那就必须根据metaclass建立出类, 因此:先定义metaclass,而后建立类。换句话说,你能够把类当作是metaclass建立出来的“实例”
一、基于__new__()方法 class Person: def __new__(cls, *args, **kwargs): if not hasattr(cls,cls._instance): # cls._instance = object.__new__(cls) cls._instance = super().__new__(cls) return cls._instance 二、基于模块导入方式,如今一个py文件中写好一个类,实例化一个对象。之后用这个类直接导入这个模块就是单例模式。 三、基于装饰器方法实现 def singleton(cls, *args, **kwargs): instance_dic = {} def inner(*args, **kwargs): if cls not in instance_dic: instance_dic['cls'] = cls(*args, **kwargs) return instance_dic['cls'] return inner @singleton class Person: pass
装饰器的写法: def wrapper(func): def inner(*args,**kwargs): '被装饰以前的操做' ret = func(*args,**kwargs) '被装饰以后的操做' return ret return inner 装饰器的应用场景: 好比注册登陆、插入日志,性能测试,事务处理,缓存等等场景
异常处理的常规写法: try: 执行的主体函数 except Exception as e: print(str(e)) 主动抛出异常: raise TypeError('出现了难以想象的异常')#TypeError能够是任意的错误类
MRO(Method Resolution Order 方法解析顺序)是面向对象中用于查询类的多继承的继承顺序的方法,它是基于算法来实现的,不一样的算法实现的MRO的顺序不一样
isinstance做用是来判断一个对象是不是一个已知的类型
Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1] 代码实现 def func(li,target): try: for i in range(0,len(li)): num = target-li[i] if num in li: return [i,li.index(num)] except:print('li类型为数组类型,内的元素需是整型,target也为整型,请检查') else:return None
一、能够处理的数据类型是 string、int、list、tuple、dict、bool、null 二、定制支持datetime类型 --------------------------官方文档的memo----------------------------------------------- >>> import json >>> class ComplexEncoder(json.JSONEncoder): ... def default(self, obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... return json.JSONEncoder.default(self, obj) ... >>> dumps(2 + 1j, cls=ComplexEncoder) '[2.0, 1.0]' >>> ComplexEncoder().encode(2 + 1j) '[2.0, 1.0]' >>> list(ComplexEncoder().iterencode(2 + 1j)) ['[', '2.0', ', ', '1.0', ']'] ---------------------------------------------------------------------------------------- import json import datetime ret = datetime.datetime.now() class CJsonEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime.date): return obj.strftime('%Y-%m-%d %H:%M:%S') else: return json.JSONEncoder.default(self, obj) print(json.dumps(ret,cls=CJsonEncoder))
在序列化是将json.dumps中的默认参数ensure_ascii改成False就能够保留中文了 json.dumps(obj,ensure_ascii=False)
assert 条件,'自定义错误提示(无关紧要)' 例:assert 1 == 0,'这是一个低级的错误' 合约式设计是断言的经典应用,在一个正确的程序里,全部的前置条件和后置条件都将获得处理。
方法一:递归处理 import os url = r'C:\Users\Mr.Wang\PycharmProjects\untitled\前段学习' def check_file(url,li = []): if os.path.isdir(url): file_list = os.listdir(url) for ret in file_list: base_url = os.path.join(url,ret) if os.path.isfile(base_url): li.append(ret) else: check_file(base_url) return li else:return os.path.basename(url) 方法二:堆栈的思想处理 import os url = r'C:\Users\Mr.Wang\PycharmProjects\untitled\python基础' lis = [url] while lis: url = lis.pop() ret_list = os.listdir(url) for name in ret_list: abs_path = os.path.join(url,name) if os.path.isdir(abs_path): lis.append(abs_path) else:print(name)
yield 是一个相似 return 的关键字,只是这个函数返回的是个生成器当你调用这个函数的时候, 函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象,当你使用for进行迭代的时候, 函数中的代码才会执行 yield from 的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器链接起来, 这样两者能够直接发送和产出值,还能够直接传入异常,而不用在位于中间的协程中添加大量处理异常的样板代码。 有了这个结构,协程能够经过之前不可能的方式委托职责。 更多解析详见:http://blog.gusibi.com/post/python-coroutine-yield-from/
import random s = '' for i in range(6): num = random.randint(0,9) alpha1 = chr(random.randint(65,90)) alpha2 = chr(random.randint(97,122)) ret = random.choice([num,alpha1,alpha2]) s += str(ret) print(s)
import random def red_packge(money,num): li = random.sample(range(1,money*100),num-1) li.extend([0,money*100]) li.sort() return [(li[index+1]-li[index])/100 for index in range(num)] ret = red_packge(100,10) print(ret) --------------------------生成器版------------------------------------------- import random def red_packge(money,num): li = random.sample(range(1,money*100),num-1) li.extend([0,money*100]) li.sort() for index in range(num): yield (li[index+1]-li[index])/100 ret = red_packge(100,10) print(ret)
(1) a=[1, 2, 3, 4, 5], a[::2]=? a[-2:]=? a[::2]=[1,3,5], a[-2:] = [4,5] (2)一行代码实现对列表a中的偶数位置的元素进行加3后求和? sum([i+3 for i in a[::2]]) (3)将列表a的元素顺序打乱,再对a进行排序获得列表b,而后把a和b按元素顺序构造一个字典d。 import random random.shuffle(a) b=a.sort() d={} for i in range(len(a)):d[a[i]] = b[i]
从三个方面来讲,一对象的引用计数机制,二垃圾回收机制,三内存池机制html
可使用re模块中的sub()函数或者subn()函数来进行查询和替换,比replace的功能更强大!!!
格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是须要被替换的文本,count是一个可选参数,指最大被替换的数量)java
import re p=re.compile("blue|white|red") print(p.sub('colour','blue socks and red shoes')) print(p.sub('colour','blue socks and red shoes',count=1))
subn()方法执行的效果跟sub()同样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量python