Python知识笔记

python知识笔记

python setup.py install

[::-1] list倒序
for k in dict 只能够遍历出字典中的key,当你想要遍历键值对是,需要遍历dict.items()
遍历dict的keys以及values时,key与value的对应关系是一一对应的,所以先遍历keys再遍历values,最后也不会乱序
''.join(),在join里面需要一个iterate对象,join前面的string将作为连接词加入新字符串中
讲python变量中的‘,“转化为MYSQL里面的’,”时,需要在符号前面加上三个\,其中一个为python转义需要,两个\为MYSQL内部需要

上下文管理器,典型应用: try except finally,以及 with。。as。。
上下文管理器的一个重要的作用就是保证有操作一定会被执行,最普通的打开文件使用 with open(xxx) as f,那么f就是上下文管理器生成的一个对象,这个对象有两个内置方法,enter以及exit,无论打开文件之后操作成功与否,最后文件总是能够被正常关闭;
同理,在操作数据库的时候使用try方法来执行数据库操作,如果出现异常,进行捕获,写入日志系统,然后考虑是否进行回滚,最后在finally方法中,关闭数据库链接
yield不只是一个语法糖,也可以作为一个表达式
当使用 a = yield value的时候,可以配合生成器.send(value)一起使用,每次send的时候,a可以接收到send过去的值

time.strptime(str, 格式), 根据给定格式从给定字符串中获取time结构变量
time.strftime(格式,time),将给定time结构变量根据给定的格式,转换为字符串

初始化数据库时,建立cursor时,cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
这样在使用fetchall方法获取数据时,所有数据都是字典类型的了,会带上列名作为key

python中子类不会继承父类的init方法,子类需要构建自己的init方法,同时调用父类方法时需要使用self.父类名称.method来调用,子类如果需要实现父类的一些初始化步骤,则可以在init方法里面父类名称.init()来进行父类参数的初始化
dict会返回当前对象的所有成员变量信息(字典格式), dir(Object)对返回对象所有的属性、变量、方法信息
json.dumps(data,default=lambda obj: obj.dict)),此语句将传入的data(python中的对象)转换为JSON格式的数据,但是json库不知道data的结构,需要在default参数中导入一个函数,这里用lambda定义一个函数返回对象的成员变量信息,这样json库就可以正常解析data对象,发挥类似于dict字典的json数据

数组元素为字典,按照字典中某个key的value来排序:
dict_list.sort(key= lambda k: k.get('字典key的name'), reverse=True) #reverse为True表示排序是由大到小
按字母排序的时候一定要考虑大小写,如果 无视大小写排序的话,一定要在排序之前做upper,lower处理

使用try except finally的时候,一定要加上except语句,加上之后程序才知道如何处理异常,如果需要无视异常,则直接在except后面加一个pass,然后语句会转到finally中进行处理
ruby中的symbol对象和string对象不一样,每个字符串都会是一个单独的string对象,但是如果设置为symbol后,内容相同的symbol字符串会是相同的对象,这样可以显著降低ruby程序的开销

在处理传入的字典类型数据的时候,取特定key对应的value,最好使用dict.get()方法,因为如果直接用dict[key]来调用值的话,如果key不存在,则会报错
用get方法的话,如果key不存在,则只会返回None,不影响程序的执行, 也可以使用get('key_name', default_value)的形式,如果查询不要指定的key,则会返回默认值

使用静态方法@staticmethod装饰器之后,直接使用ClassName.staticmethodName的形式调用静态方法,不需要提前创建对象
处理字符串数据的时候,有时候需要解析带有引号的原有变量,可以用eval()方法可以进行类型转换,但是eval方法无法处理原本就是字符串类型的变量,所以处理前要进行类型判断

leftjoin,以左表为基础,先展示左表的全部数据,然后再展示右表中符合条件的数据(如果没有相关的值,则置为null)
同理rightjoin,以右表为基础,先展示右边,再展示 左表中符合条件的记录, 如果使用Inner Join的话,则会根据给出的条件来进行结果显示,如果没有符合的结果的话则什么都不会显示

类似于遍历JSON格式数据这种工作,利用递归实现是可以的,因为JSON的层级不会无限深,所以递归的层级不会过深,递归的效率低下的主要原因是内部堆栈的时候会在每一次递归的时候建立新栈,浪费系统资源,如果递归层级很深的话,最好就不要使用递归了

对于字典操作的时候一般采用深拷贝方法,对于list,如果List内部的元素不是可变对象的话,直接用切片操作([:])或者工厂方法就可以实现与拷贝一样的效果了

python3.X是兼容python2.7的语法的,所以平时写代码的时候尽量以python3的风格来写代码,例如print后面带上括号。。

在SQL查询中涉及中文字段进行排序的时候,需要先将该字段进行编码转换,使用convert(xxx using gbk)将其转换为gbk字符集,最终排序结果会数字在前,字母在后,中文在最后

ruby当中,module::class.method可以简便的调用module下面类中的类方法,如果是实例方法,则先创建对象再调用,module::class.new.method
类变量@@,实例变量@,类变量和类相关联,被子类继承,子类中对类变量修改后,父类的类变量也一并被修改,实例变量与实例关联,每一次新建的实例都有自己的实例变量
最通常的用法是在类定义当中使用attr_accessor关键字定义实例变量同时定义实例变量的访问器方法,然后在initialize方法中初始化实例变量(在类中初始化的实例变量是不会被实例获取的)
在类中声明的实例变量和类变量只能被类本身访问,比如说类方法就可以访问,而实例方法不可以(实例方法是实例而不是类本身)

在部署环境上面尝试用alias来启动server与停止server,但是有几个问题,一个是alias里面语句要包括在引号里面,然后本身要映射的语句里面也是有引号的,这个时候就要注意在外层一般是用"号,内层用'的,然后又一些特殊符号需要使用转义符,比如; 还有一个问题就是python的服务启动命令在部署的时候要写成相对路径,是需要与前端的代码保持一致,前端代码里面使用的就是相对路径,使用绝对路径会找不到template文件
现在已经使用了supervisor工具来启动和停止server了,supervisor可以在配置文件当中指定启动的进程路径以及进程数目,同时还可以配置进程组,启动的时候可以直接启动一组进程,然后通过supervisor启动的所有进程都是supervisor主进程的子进程,supoervisor会作为子进程的守护进程,保证子进程不会意外被kill

strip只能去除首尾的字符,默认为去除空格,lstrip、rstrip分别为操作左右两边

sorted方法里面指定key的时候,可以指定一个tuple作为key,然后排序的时候会按照tuple里面的顺序来一次对Iteration对象进行排序

一般的函数也有叫法叫做子例程、或者过程,一般的函数会有一个入口(传参)以及一个出口(return),有一种特殊的子例程叫协程,协程可以有多个入口,允许从一个入口执行到下一个入口之前暂停,系统为它保存状态,然后等到合适的时机从下一个入口点恢复执行;
在GIL的影响下,python多线程仅仅对IO密集型的任务有优化作用,对于CPU密集型任务,多线程甚至要比单线程要慢

事务处理中,X锁:排它锁(只允许事务本身去读取和修改数据,保证事务期间其它事务无法), S锁:共享锁(让事务本身只能读数据对象而不能修改数据对象,其它事务也只能给数据对象加S锁而不能加X锁)

典型的发送post至对端接口,然后接收处理返回的post消息:
发过去的post的body为一个json,就先在header中声明数据类型:header = {"content-type = application/json"}
然后再使用requests.post(url, json, header)来发送并得到post响应
最后使用json.loads(response.content, encode)来解析返回的json数据

在生产环境上面做紧急修改的时候,最好使用本地的文件去替换环境上面的文件,直接用vim编辑器写代码会有缩进上面的问题

python project当中如果出现一些import导致的问题,主要原因两大类,一类是路径的问题(项目当中子目录下面都需要建立一个init.py),一类是交叉引用问题,避免交叉引用最有效的方法就是保证A引用B,B就不要引用A了

在python当中,名称前面加单下划线的方法为私有方法,标识此方法不属于api,带双下划线_的命名表示此方法不能被子类覆盖,且此方法仅能在类内部使用 self.__method
但是也不是不可以在外面使用,在外面使用的话,使用 instance._classname__menthod()的方式调用
至于前后都带双下划线的变量或者方法,表明这些都是提供给python使用的

在项目代码当中,疑惑一个机制的实现方法,最好的方法是使用调试来学习处理步骤,如果调试不可用的话,那么根据最初的方法找到后台低层实现,然后找寻低层方法的usage来一层一层往上面找,最后找到实际的应用层函数方法;

@classmethod、@staticmethod、@property
@classmethod注释的方法可以使用 ClassName.methodname()、 Instance.methodname()两种形式调用,主要用途在于表示此方法用于类内部使用;
声明的时候带上cls参数,表示类本身

@property方法注释的method,可以直接使用 Instance.method来访问,就是method后面不需要带括号了,就感觉像是访问属性一样

左斜杠在字符串里面一般会被识别为转义符,会将斜杠旁边的符号转义,所以使用的时候需要注意,要表示斜杠本身,需要同时使用两个斜杠出来\,所以在windows下面读取路径斜杠需要使用\
在填写路径字符串的时候在左引号旁边写一个r,可以不使用转义符,表示字符串为原始的字符串

输入可变参数,默认定义名称为args、kwargs,前者会被读取为一个List,后者为一个Dict,名称可以随便定义,只要是一个开头都是List,两个开头为Dict
args和kwargs前面的
符号的真正意义是将List、Dict解包,然后将List、Dict当中的元素作为函数参数来使用;
a = [1,9], range(*a) => 结果为1,2,3,4,5,6,7,8;将a中的1和9作为参数输入到range函数当中去;
同理Dict解包后,key作为参数名称,value作为参数值输入函数当中

看到有一些Function的定义的时候加入了self作为输入参数,有点看不懂为啥明明这个function不是一个Class里面定义的Function,但是可以输入self作为参数,这里其实就体现了python是一种动态语言

init.py文件的作用是标识一个python包,当我们导入一个package的时候,其实是导入的这个init.py文件,如果里面有内容的话,会执行里面的内容,比如说在init.py里面写入一些相关联的依赖包,那么在导入一个包的时候就可以一并导入一些依赖的包了; 同时也可以在里面做对象的实例化,那么导入的时候就可以实际import一个对象进去了

re.split()为可以使用正则的split方法,里面根据正则获取到的字符来分割输入的字符串,同时可以使用非获取方式(术语叫做零宽度断言)
re.sub()为使用指定的字段,替换掉正则匹配到的字段

os.path.isfile/os.path.isdir/ os.path.basename / os.path.listdir / os.walk

装饰器也可以用于声明Class的时候,典型应用就是装饰一个Class让其实例化单例对象

子类继承父类的时候,也可以继承父类的实例变量,但是在初始化方法(init)当中需要调用父类的初始化方法完成所要继承的实例变量的初始化, parent_class_name.init(self, 变量1, 变量2)

python的re模块进行正则匹配的时候,最简便的用法是使用re.match来获取所有匹配的信息,但是有一个地方要注意就是,re.match是默认从左往右匹配上整个字符串的,如果想要匹配上字符串的右边结尾处,需要在左边加上通配符以满足对整个字符串的匹配,要不然返回的匹配结果为空

使用协程的时候,@run_on_executor装饰器与最初的生成器方法不需要处于同一个目录中或者同一个Class当中,其本质为加入tornado后台的IOLoop当中,当前的IOLoop_on_current仅有一个,所以无论executor方法在哪里都是可以加入到IOLoop当中的

使用os.walk()快速遍历目录下的子目录以及文件,os.walk(top, topdown, onerror, followlinks), top为想要遍历的目录,topdown设置先遍历子目录还是先遍历根目录;
函数返回一个生成器,生成器返回一个元组,(目录路径, 目录名称, 目录中的文件list)

VIM下跳转至最后一行,shift+g

在调试的时候可以临时打上新的断点,然后直接F9跳转到想要的地方,然后跳过去以后,再打下一个断点,再继续进行调试,典型应用就是在进入循环的时候,在循环外面打一个断点就可以跳出当前的循环了(eclipse里面也可以这么搞啊,我终于学到了)

在python当中,字符串、数字、tuple都是属于不可变对象,不可变的意思就是对象无法在基于原地址的情况下修改,比如 a='abc', 如果让a的值产生了变化,实际上后台会重新创建一个新的字符串对象,而不是为之前在那个地址的对象赋一个新值;
同样的,List、Dict就是可变对象,对象的值可以在原地址的基础上进行修改,这样会造成一个现象就是多个List、Dict对象可能都指向同一个地址,对于一个对象进行操作之后会影响所有指向该地址的对象;
a = b = [1,2,3] a.append(4) 此时a和b的值都变为[1,2,3,4]

使用id(instance)的方法来查看当前对象的内存地址, 在python当中所有赋值操作都是地址引用,只不过对于可变对象和不可变对象在改变值的时候会有处理上面的差异
浅拷贝: copy库当中的copy方法,copy方法会在原对象的基础之上创建一个新对象,但是对于原对象内部的元素,如果该元素是可变对象的话,则会直接引用地址,不会创建新对象; 比如copy List的时候,对于List内部的List就只是引用地址而已; 在python当中,切片操作、List工厂方法、copy函数都会实现浅拷贝的效果;

深拷贝: copy库当中的deepcopy方法,对于原对象当中的所有元素均会进行新的对象创建,对于复杂参数的List、Dict可以考虑使用深拷贝(速度会相应的下降,创建新对象的时候会创建缓存记录所有要拷贝的对象)

子类当中如果没有复写父类的方法,则子类都会继承这些方法,包括初始化init方法

type函数: type( name of the class, tuple of tghe parent class, dictionary containing attributes names and values ),换一种思路,在使用type(var)的时候,能显示出var的类型,其实这个类型不就是用来创建var的class么

在使用"".format的时候,字符串文本里面使用{}来做一个placeholder,当字符串里面需要真正的{}的时候,需要使用{{}}的形式来标识{},然后在写sql语句的时候,{}内容为字符串的时候,注意要加上引号

你可能感兴趣的:(Python知识笔记)