python 杂记20191102 虚拟环境pipenv
权限系统要考虑:页面权限, 操作权限, 数据权限 :https://mp.weixin.qq.com/s/XXCDaPP4DTHKLBzsamND2A
=====
__init__.py 会在 import 的时候被执行
configparser在python中该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)
============
try...except Exception as e 其中的e代表什么意思呢?
Exception匹配了所有异常,把异常名称赋给了e。
============
上下文管理器:
def __exit__(self, exc_type, exc_val, exc_tb):
若exc_tb不是空,则说明有异常
返回值只能是true或false,若是false,则会把之前发生的异常抛出来
===========
可以定义一个枚举类来管理一些常量
=====使用顺序
==========自定义字符串比较大小的方法
class MY_CMP(str): def __lt__(self,y): return self+y>y+self
ru=[3,2,43,56,70,7,11,9] aa=list(map(str,ru)) aa.sort(key=MY_CMP)
=====================
安装虚拟环境的工具:pipenv
安装pipenv: pip install pipenv
使用 pipenv --venv 命令可以 查看项 目对应的虚拟环境路径
到一个目录下创建虚拟环境:pipenv install
进入虚拟环境:pipenv shell
给虚拟环境安装flask:pipenv install flask
查看安装包的依赖:pipenv graph
退出虚拟环境:exit
允许你不显式激活虚拟环境即可在当前项目的虚拟环境中执行命令:pipenv run python hello.py
数据库可视化工具:Navicat [可以是mysql的可视化工具]
===============
网盘搜索:https://www.dalipan.com/?from=enfi_desktop
=======装饰器
from functools import wraps def my_decrate(f): @wraps(f) def tst(*args,**kwargs): print('befor') ret=f(*args,**kwargs) print('after') return ret return tst @my_decrate # 没参数的装饰器 def tt(name,age): print('hello,name=%s,age=%s'%(name,age)) def logit(lala=' out.log'): #有参数装饰器的定义 def logging_decorator(func): @wraps(func) def wrapped_function(*args, **kwargs): log_string = func.__name__ + " was called" print(log_string+lala) return func(*args, **kwargs) return wrapped_function return logging_decorator @logit() #有参数的装饰器,加了() def sdf(name,age): print('hello,name=%s,age=%s'%(name,age)) @logit(lala=' haha') def sdf2(name,age): print('hello,name=%s,age=%s'%(name,age))
定义类装饰器
类装饰器的调用
==========多维数组
from collections import defaultdict import json def tst(): return defaultdict(tst) users = tst() users['core']['ip'] = 'hrldcpr' users['core']['port'] = 'matthandlersux' users['age']=18 users['wfids']["tree"]['leaf']=990 print(users['core']['port']) # matthandlersux print(users['age']) # 18 print(json.dumps(users)) # {"core": {"ip": "hrldcpr", "port": "matthandlersux"}, "age": 18, "wfids": {"tree": {"leaf": 990}}}
===========
生成器是一种使用普通函数语法定义的迭代器 。
实现了方法__iter__的对象是可迭代的,
而实现了方法__iter__和__next__的对象是迭代器
包含yield语句的函数都被称为生成器(生成器也有方法__iter__和__next__)
#自定义生成器 class tst(object): def __init__(self,n): self.n=n self.i =1 def __iter__(self): return self def __next__(self): if self.i >self.n: raise StopIteration() i=self.i self.i +=1 return i
aa=tst(3)
print('==11111=====')
for j in aa:
print(j)
print('==3333=====')
for j in aa: # 迭代器只能消费一次,所以没打印
print(j)
print('=======')
结果
==11111=====
1
2
3
==3333=====
=======
可以使用chardet模块来检测文件中的字符集合。这在分析大量随机文本时非常有用。安装chardet模块
==============
匿名函数:lambda 参数:操作(参数) 你不想在程序中对⼀个函数使⽤两次, 你也许会想⽤lambda表达式
for循环还有⼀个else从句, 这个else从句会在循环正常结束时执⾏。 这意味着, 循环没有遇到任何break.
ctypes接⼜允许我们在调⽤C函数时使⽤原⽣Python中默认的字符串型和整型 ,⽽对于其他类似布尔型和浮点型这样的类型, 必须要使⽤正确的ctype类型才可以
=============
如果__exit__返回的是True以外的任何东西, 那么这个异常将被with语句抛出
我们来写⼀个程序, 读取⼀个⽂件, 检测它是否是JPG(提⽰: 这些⽂件头部以字节FF D8开始) :jpgdata.startswith(b'\xff\xd8')
在Python中当函数被定义时, 默认参数只会运算⼀次, ⽽不是每次被调⽤时都会重新运算。 你应该永远不要定义可变类型的默认参数
===========用yield实现一个协程
def grep(pattern):
print("Searching for", pattern)
while True:
line = (yield)
if pattern in line:
print(line)
tst = grep('love')
next(tst) # 启动协程,执行yield表达式
tst.send('i love you')
tst.send('do you love me')
tst.send('yes i do')
tst.close() # 关闭协程
==对二进制进行编码:base64.b64encode
所谓转义就是不采用符号本来的含义,而是采用另外一种含义。如\n指换行,\r指回车。
可以使用r取消转义,如r"c:\news"
Unicode编码通常是2个字节。
UTF-8:常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码.
f=open("tst.txt")
f.tell() #指针所在位置
f.seek(4) #将指针定位到从开头的第四个字符后面
封装就是让别人看不到,就是定义私有属性和方法
特殊方法:两个对象是否能进行加法运算,首先要看对象是否有__add__方法
__slot__已经把实例属性管控起来了,若要增加属性,只能通过类属性来实现
__setattr__(self,name,value):给name属性赋值时就调用这个方法
__getattr__(self,name):name被访问且它不存在时会调用此方法
__getattribute__(self,name):name被访问时被调用,无论name是否存在
def __setattr__(self,name,value): print("tst for fun") self.__dict__[name]=value def __getattribute__(self,name): print('aaaaaaa") return object.__getattribute__(self,name) def __getattr__(self,name): if name == "size" return self.width,self.length esle: raise AttributeError
=======
__打头的变量是私有变量,不能被子类继承,对应的实例也不能访问
_打头的变量是protect的,可以被子类继承,实例可以访问,不能在其他模块import
from hah import * print('begin') print(eae.name) print(_eye.name) # 会报错
========拷贝
import copy t1={'name':'t1'} t2={'name':'t2','son':t1} t3=t2 t4=copy.copy(t2) t5=copy.deepcopy(t2) t1['age1']=10 t2['age2']=18 print('t3 ',t3," t4 ",t4," t5 ",t5)
==========
主要区别在于sys.path
不同
直接运行会将该脚本所在目录添加至sys.path
当做模块启动则会将当前运行命令的路径添加至sys.path
deque提供了⼀个双端队列, 你可以从头/尾两端添加或删除元素.
我们也可以限制这个列表的⼤⼩, 当超出你设定的限制时, 数据会从对队列另⼀端被挤出去(pop)。
捕获多个异常:except (IOError, EOFError) as e:
for循环还有个else从句,这个else从句会在循环正常结束时执。这意味着,循环没有遇到任何break.
检测文件是否是JPG(这些文件头部以字节FF D8开始): if jpgdata.startswith(b'\xff\xd8'):
==============
计算字符长度
def str_byte_len(mystr):
return (len(mystr.encode('utf-8')))
str_byte_len('i love python') # 13(个字节)
str_byte_len('字符') # 6(个字节)
过滤掉各种空值
def filter_false(lst):
return list(filter(bool, lst))
filter_false([None, 0, False, '', [], 'ok', [1, 2]])# ['ok', [1, 2]]
嵌套数组完全展开
from collections.abc import *
def flatten(input_arr, output_arr=None):
if output_arr is None:
output_arr = []
for ele in input_arr:
if isinstance(ele, Iterable): # 判断ele是否可迭代
flatten(ele, output_arr) # 尾数递归
else:
output_arr.append(ele) # 产生结果
return output_arr
flatten([[1,2,3],[4,5]], [6,7]) # [6, 7, 1, 2, 3, 4, 5]
对象转换为可迭代类型
from collections.abc import Iterable
def cast_iterable(val):
return val if isinstance(val, Iterable) else [val]
cast_iterable('foo')# foo
cast_iterable(12)# [12]
cast_iterable({'foo': 12})# {'foo': 12}
检查list是否有重复元素
def has_duplicates(lst):
return len(lst) == len(set(lst))
列表翻转
def reverse(lst):
return lst[::-1]
互为变位词
from collections import Counter
# 检查两个字符串是否 相同字母异序词,简称:互为变位词
def anagram(str1, str2):
return Counter(str1) == Counter(str2)
anagram('eleven+two', 'twelve+one') # True 这是一对神器的变位词
anagram('eleven', 'twelve') # False
是否为变位词;
方法1:
def isAnagrams(self, str1, str2):
if sorted (str1) == sorted(str2):
return True
return False
方法2:
class Solution:
def anagram(self, s, t):
return collections.Counter(s) == collections.Counter(t)
给定一个字符串 S,找出 S 中最长的回文字符串:最简单的方案,穷举所有可能的子串,判断子串是否为回文
class Solution: # @param {string} s input string # @return {string} the longest palindromic substring def longestPalindrome(self, s): if not s: return "" n = len(s) longest, left, right = 0, 0, 0 for i in xrange(0, n): for j in xrange(i + 1, n + 1): substr = s[i:j] if self.isPalindrome(substr) and len(substr) > longest: longest = len(substr) left, right = i, j # construct longest substr result = s[left:right] return result def isPalindrome(self, s): if not s: return False # reverse compare return s == s[::-1]