python 杂记

sqlalchemy: https://docs.sqlalchemy.org/en/14/orm/quickstart.html 

swagger:https://mp.weixin.qq.com/s/0TzOKmxI3vxN50CYMtxCdQ

 json.dumps(data, indent='\t', ensure_ascii=False, separators=(',', ':'))

 在Python 3中,异常对象在 except代码块作用域之外是无法访问的

模块之间出现循环依赖(circular dependencies)

假设你有两个文件,分别是 a.pyb.py,二者相互引用,如下所示:

a.py文件中的代码:

b.py文件中的代码:

首先,我们尝试导入 a.py模块:

代码运行正常。也许这出乎了你的意料。毕竟,我们这里存在循环引用这个问题,想必应该是会出现问题的,难道不是吗?

答案是,仅仅存在循环引用的情况本身并不会导致问题。如果一个模块已经被引用了,Python可以做到不再次进行引用。但是如果每个模块试图访问其他模块定义的函数或变量的时机不对,那么你就很可能陷入困境。

那么回到我们的示例,当我们导入 a.py模块时,它在引用 b.py模块时是不会出现问题的,因为 b.py模块在被引用时,并不需要访问在 a.py模块中定义的任何变量或函数。 b.py模块中对a模块唯一的引用,就是调用了a模块的 foo()函数。但是那个函数调用发生在 g()函数当中,而 a.pyb.py模块中都没有调用 g()函数。所以,不会出现问题。

但是,如果我们试着导入 b.py模块呢(即之前没有引用 a.py模块的前提下):

糟糕。情况不太妙!这里的问题是,在导入 b.py的过程中,它试图引用 a.py模块,而 a.py模块接着又要调用 foo()函数,这个 foo()函数接着又试图去访问 b.x变量。但是这个时候, b.x变量还没有被定义,所以才出现了AttributeError异常。

解决这个问题有一种非常简单的方法,就是简单地修改下 b.py模块,在 g()函数内部才引用 a.py

现在我们再导入 b.py模块的话,就不会出现任何问题了

================================

 在遍历列表时更改列表:能够做到这点的一个编程范式就是列表解析式

==================

错误理解Python中的变量名解析

上述错误的出现,是因为当你在某个作用域内为变量赋值时,该变量被Python解释器自动视作该作用域的本地变量,并会取代任何上一层作用域中相同名称的变量。

正是因为这样,才会出现一开始好好的代码,在某个函数内部添加了一个赋值语句之后却出现了 UnboundLocalError,难怪会让许多人吃惊。

foo1函数并没有为 lst变量进行赋值,但是 foo2却有赋值。我们知道, lst+=[5]只是 lst=lst+[5]的简写,从中我们就可以看出, foo2函数在尝试为 lst赋值(因此,被Python解释器认为是函数本地作用域的变量)。但是,我们希望为 lst赋的值却又是基于 lst变量本身(这时,也被认为是函数本地作用域内的变量),也就是说该变量还没有被定义。

=====================

可选参数默认值的设置在Python中只会被执行一次,也就是定义该函数的时候。因此,只有当 foo()函数被定义时, bar参数才会被初始化为默认值(也就是,一个空列表),但是之后每次 foo()函数被调用时,都会继续使用 bar参数原先初始化生成的那个列表

一个常见的解决办法就是:

 

==============================

1 导入模块多次和导入一次的效果是一样的

2 若希望模块能像程序一样被执行,可以使用-m切换开关来执行,如python -m progname args (运行带命令行参数args的progname程序)

3 模块真正的用处在于它可以保持自己的作用域

4 告知模块本身是作为程序运行还是导入到其他程序,需要使用__name__变量,被当做程序执行时,__name__的值是__main__,被导入时,值为模块的名字

5 模块存储在文件中,包就是模块所在的目录,为了让python将目录作为包对待,目录必须包含一个__init__.py的文件(模块)

6若将__init__.py作为普通模块导入的话,__init__.py模块的内容就是包的内容。如constants包的__init__.py包括PI=3.14,那么可以像下面这样做:import constants  print constants.PI

7 非常重要的一个知识点,一定要记住

8 __all__

__all__定义了模块的公有接口

若模块有__all__变量,则__all__代表from 模块 import * 代表什么含义

不在__all__变量中的函数无法通过import *导入,如copy模块中的dispatch_table 不在__all__中,要使用dispatch_table就要通过 from copy import dispatch_table 实现,或先导入copy,再copy.dispatch_table

若模块没有__all__,则import * 默认导入模块中所有不以下划线开头的全局变量

9 想看函数的使用说明,可以打印__doc__,如 print(range.__doc__)

10 找到源码的位置:print copy.__file__

11 sys.argv列表中,脚本的名字为sys.argv[0]

12 利用heapq可以求出前N个最大最小值

import heapq

lyst = [-3, 22, 45, 34, 99, 102, -44]
low3 = heapq.nlargest(3, lyst)
top3 = heapq.nsmallest(3, lyst)

13 

为了让特殊字符表现得像普通字符一样,需要对它进行转义

profile模块可用于代码片段效率分析;trace模块可以提供总的分享

cmd 可以编写命令行解释器

14 
re.search 寻找匹配的字符,找到了返回true,没找到返回false
re.match 从字符串开头匹配,

=========================

1 open第3个参数控制着文件的缓冲,取值0则表示无缓冲,直接写磁盘;取值1则表示直接写内存,只有flush或close时才写磁盘;大于1时代表换届区大小(单位是字节),-1(或其他负数)代表使用默认缓冲区大小

2 sys.stdin sys.stdout sys.stderr :它们都是文件,大部分文件对象的方法它们也可以使用(如read)

3 随意读取使用seek:seek(offset,whence),其中offset表示偏移的字节数,whence默认是0,表示从文件开头开始偏移,取值1时表示从当前位置开始偏移,取值2时表示从文件结尾移动

4 tell返回当前文件的位置

 5 读取大文件的方法:

with open(path,'r') as f:
    for line in f:
        print(line)
print("+++++++++++")
with open(path,'r') as f:
    while True:
        line=f.readline()
        if line:
            print(line)
        else:
            break
print("+++++++++++")

 6 有双下划线的方法是私有方法

7 前面有下划线的名字都不会被带星号的Import语句导入(from module import *)

8 判断一个类是否是另一个类的子类:issubclass

9 在多重继承中,若父类中有相同名字的方法,则先继承的类中的方法会重写后续继承的类中的方法

10 判断方法是否存在:hasattr(Zcy,'haha')

调用方法:getattr(Zcy(),'haha')()

设置方法:

setattr(Zcy,'oo','ouou')
print(Zcy.oo)

def pp():
    print('pp')
setattr(Zcy,'rr',pp)
Zcy.rr()

11 

12 自己的异常类要继承自 Exception

13 若想将捕获的异常 传递出去,只需调用不带参数的raise

try:
    print(1/0)
except ZeroDivisionError:
    print("sdf")
    raise 

14 捕获多个异常

try:
    print(1/'sdf')
except (ZeroDivisionError,TypeError):
    print("sdf")

15 访问异常对象本是,下面示例中e就是异常对象本身

try:
    ss=1
    print(ss.split(','))
except (ZeroDivisionError,TypeError,AttributeError) as e:
    print(e)

 捕获所有异常用   except Exception as e:

16  调用时间不可知,不建议使用

17 若子类重写了构造方法,那么一定要调用父类的构造方法,否则子类可能不能正确的初始化

18 x[-n] 和 x[ len(x)-n] 是一样的

19 迭代器

class DD(object):
    def __init__(self):
        self.age=0
    def __iter__(self): #返回一个迭代器
        return self
    def __next__(self): # 实现了__next__ 方法的才是迭代器
        if self.age<5:
            self.age  +=1
            return self.age
        raise StopIteration

sdf=DD()
try:
    for age in sdf:
        print(age)
    print ('hello')

except Exception as ex:
    print(ex) #没有走到这里

20 生成器:任何包含yield语句的函数称为生成器

21 当使用一个负数作为步长时,必须让开始点大于结束点,如:

y=[11,22,33,5,6,7,8]
print y[6:0:-2]
输出:[8, 6, 33]

22  any: 有一个是真就返回true   【0或“”或false或None 都算是假】

     all:全部是真才返回true     

23 

 @property装饰器必须先于@setter,@deleter使用,且三者说装饰的函数必须同名

 如果一个方法被@classmethod所装饰,就代表该方法与类绑定,而不是与实例对象绑定

被@staticmethod所装饰的方法为静态方法,静态方法一般使用场景就是和类相关的操作,但是又不会依赖和改变类、实例的状态,比如一些工具方法

 24

在 queue 模块中提供了 3种同步的、线程安全的队列,分别由 3个类 Queue【先进先出】、LifoQueue【先进后出】 和 PriorityQueue【优先级队列】,它们的唯一区别是元素取出的顺序不同。并且,LifoQueue 和 PriorityQueue 都是 Queue 的子类。

25

event对象的一个重要特点是它被设置为True时会唤醒所有等待它的线程,如果唤醒单个线程的最好用Condition

26

发送x-www-form-urlencoded请求的方法之一

 

def tst():
    url = "http://127.0.0.1:8101/spec-extract-v1/"
    rds = ["*******;"]
    rds = str(rds).replace("'", '"')
    rds = parse.quote(rds)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
    }
    response = requests.request("POST", url, headers=headers, data='input_sens=' + rds)
    print(response.json())

 

posted on 2019-06-21 17:17  我和你并没有不同  阅读(317)  评论(0编辑  收藏  举报