python 基础 day5

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 基础 day5相关的知识,希望对你有一定的参考价值。

本节内容:1、双层装饰器  

         2、字符串格式化

         3、递归

         4、生成器、迭代器

         5、模块

双层装饰器

USER_INFO = {}


def check_login(func):
    def inner(*args,**kwargs):
        if USER_INFO.get(‘is_login‘,None):
            ret = func(*args,**kwargs)
            return ret
        else:
            print("请登录")
    return inner

def check_admin(func):
    def inner(*args,**kwargs):
        if USER_INFO.get(‘user_type‘,None):
            ret = func(*args,**kwargs)
            return ret
        else:
            print("无权限")
    return



@check_login
@check_admin
def index():
    print("index")


index()
#从下晚上渲染(编译解释),@chec_admin装饰index函数,它们作为一个整体,假设这个整体的名字为nindex,那么@chec_login装饰的就是nindex。
#从上往下之行,先之行@chec_login,执行里面的func也就是执行index,index就是@check_admin和index函数,接下来执行check_admin里的func,也就是执行index 函数,那它执行的就是check_admin里的inner 函数.
 

 字符串格式化

Python的字符串格式化有两种方式: 百分号方式、format方式

百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存。

百分号方式

%[(name)][flags][width].[precision]typecode
  • (name)      可选,用于选择指定的key
  • flags          可选,可供选择的值有:
    • +       右对齐;正数前加正好,负数前加负号;
    • -        左对齐;正数前无符号,负数前加负号;
    • 空格    右对齐;正数前加空格,负数前加负号;
    • 0        右对齐;正数前无符号,负数前加负号;用0填充空白处
  • width         可选,占有宽度
  • .precision   可选,小数点后保留的位数
  • typecode    必选
    • s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
    • r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
    • c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
    • o,将整数转换成 八  进制表示,并将其格式化到指定位置
    • x,将整数转换成十六进制表示,并将其格式化到指定位置
    • d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
    • e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
    • E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
    • f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
    • F,同上
    • g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)
    • G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)
    • %,当字符串中存在格式化标志时,需要用 %%表示一个百分号

注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式

常用格式化:

tp1 = "i am %s" % "QL"
print(tp1)
tp2 = "i am %s age %d" % ("QL",18)     #顺序添加
print(tp2)
tp3 = "i am %(name)s age %(age)d" %{"name":"QL","age":18,}  #命名添加
print(tp3)
tp4 = "percent %.2f" % 99.98765
print(tp4)
tp5 = "i am %(pp).2f %%" %{"pp":123.2312444,} #可以命名也可以不命名
print(tp5)
tp6 = "i am %.2f %%" % 123.123123   #显示百分号,需要写两个% 相当于转译
print(tp6)

s = "我是%(name)s age %(age)d" % {‘name‘:‘QL‘,‘age‘:21}
print(s)
#我是QL age 21

s1 = "我是%(name)-10saa %(age) +10daa" %{‘name‘:‘QL‘,‘age‘:12}
print(s1)
#我是QL        aa        +12aa

s2 = "hello %c------%o=====%x" % (65,15,15)  #%c是asc码,%o是8进制,%x16进制
print(s2)
#hello A------17=====f

 format 方式

[[fill]align][sign][#][0][width][,][.precision][type]

    • fill           【可选】空白处填充的字符
    • align        【可选】对齐方式(需配合width使用)
      • <,内容左对齐
      • >,内容右对齐(默认)
      • =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
      • ^,内容居中
    • sign         【可选】有无符号数字
      • +,正号加正,负号加负;
      •  -,正号不变,负号加负;
      • 空格 ,正号空格,负号加负;
    • #            【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
    • ,            【可选】为数字添加分隔符,如:1,000,000
    • width       【可选】格式化位所占宽度
    • .precision 【可选】小数位保留精度
    • type         【可选】格式化类型
      • 传入” 字符串类型 “的参数
        • s,格式化字符串类型数据
        • 空白,未指定类型,则默认是None,同s
      • 传入“ 整数类型 ”的参数
        • b,将10进制整数自动转换成2进制表示然后格式化
        • c,将10进制整数自动转换为其对应的unicode字符
        • d,十进制整数
        • o,将10进制整数自动转换成8进制表示然后格式化;
        • x,将10进制整数自动转换成16进制表示然后格式化(小写x)
        • X,将10进制整数自动转换成16进制表示然后格式化(大写X)
      • 传入“ 浮点型或小数类型 ”的参数
        • e, 转换为科学计数法(小写e)表示,然后格式化;
        • E, 转换为科学计数法(大写E)表示,然后格式化;
        • f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
        • F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
        • g, 自动在e和f中切换
        • G, 自动在E和F中切换
        • %,显示百分比(默认显示小数点后6位)

常用格式化

s1 = "----{:9^20s}====={:d}====={:x}".format(‘QL‘,16,15) #x是16进制
print(s1)
#----999999999QL999999999=====16=====f

s2 = "sddddsssss {:.2%}".format(0.1334234)  #把数字自动转换成百分比形式,并且保留2位小数
print(s2)
#sddddsssss 13.34%

tp1 = "i am {},age {}, {}".format("seven",18,‘QL‘)
print(tp1)
#i am seven,age 18, QL

tp2 = "i am {},age {}, {}".format(*["seven",18,"QL"]) #列表传递前面要加*
print(tp2)
tp3 = "i am {0},age {1},really {0}".format("seven",18)
print(tp3)
#i am seven,age 18,really seven

tp4 = "i am {name},age{age},really {name}".format(name="seven",age=18)
print(tp4)

tp5 = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])  #元素传递
print(tp5)

tp6 = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
  
tp7 = "i am {:s}, age {:d}".format(*["seven", 18])
  
tp8 = "i am {name:s}, age {age:d}".format(name="seven", age=18)
  
tp9 = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
 
tp10 = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl1 = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl2 = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
 
tpl3 = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)

 

递归

#无返回值,None

def d():
    return‘123‘


def c():
    r = d()
    return r

def b():
    r =c()
    return r

def a():
    r =b()
    print(r)

a()


def func(n):
    n +=1
    if n >=4:
        return "end"
    return func(n)

r = func(1)
print(r)
#思考题:1*2*3*4*5*6

 

迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
>>> a = iter([1,2,3,4,5])
>>> a
<list_iterator object at 0x101402630>
>>> a.__next__()
1
>>> a.__next__()
2
>>> a.__next__()
3
>>> a.__next__()
4
>>> a.__next__()
5
>>> a.__next__()

生成器

一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;

def func():
    print("aaaa")
    yield 1
    yield 2
    print("ccc")
    yield 3

 上述代码中:func是函数称为生成器,当执行此函数func()时会得到一个迭代器。 

ret = func()

r1 = ret.__next__()
print(r1)
r2 = ret.__next__()
print(r2)
r3 = ret.__next__()
print(r3)

#结果
aaaa
1
2
ccc
3

 实例:

用生成器自定义range

def myrange(arg):
    start = 0
    while True:
        if start > arg:
            return
        yield start
        start += 1

ret = myrange(5)
r = ret.__next__()
print(r)

r1 = ret.__next__()
print(r1)

r2 = ret.__next__()
print(r2)

#结果
0
1
2

 

模块

模块  (在其他语言里叫类库)

分为三类:
    1、开发者写的模块
    2、第三方模块
    3、自定义模块

为什么要有模块?

将代码归类

 

先导入,后使用(.py,或者是一个文件夹包含很多.py)

import s1  #一个.py
import lib.commons    #一个文件夹包含多个.py

#调用 f2是s1.py里的函数,f1是lib下的commons.py里的函数
s1.f2()
lib.commons.f1()
from s1 import *  
from s1 import f2  #s1模块名,f2是s1里的函数

f2()

from lib import commons
from src import commons as src_commons  #如果两个文件夹里有相同模块名自可以定义别名

commons.f1()

 

#模块名字非常重要*********
#创建模块名不要和内置模块名一样,先寻找当前目录,找到就不再往下找了,就不会调用内置模块了

 

查找python 路径

import sys
for item in sys.path:
    print(item)

#查找结果,我所使用的是pycharm,并建立了一个s13的项目文件,下面建立了一个day5文件夹,程序就放在这里面

C:\\Users\\qinling\\PycharmProjects\\s13\\day5
C:\\Users\\qinling\\PycharmProjects\\s13        #先在当前目录找模块  在pycharm下会导入项目目录,但在Linux下是不会导入的,所以忽略此目录
C:\\Users\\qinling\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip
C:\\Users\\qinling\\AppData\\Local\\Programs\\Python\\Python35\\DLLs
C:\\Users\\qinling\\AppData\\Local\\Programs\\Python\\Python35\\lib
C:\\Users\\qinling\\AppData\\Local\\Programs\\Python\\Python35
C:\\Users\\qinling\\AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages #第三方模块存放位置 

sys.path.append(‘E:\\\\‘) #导入E盘位置,sys.path是列表,添加python路径 
 

 

推荐使用导入方法:

单模块:
     import

嵌套在文件夹下:
     from xxx import xxx
     from xxx import xxx as xxxxx

 

安装第三方模块

1、pip 安装(pip3,python3有,python2,没有)

2、源码安装:

      解压进入目录

      执行 python3  setup.py  install

例如安装requests模块:

pip3 install requests  #找到requests模块文件位置 用这个命令安装
python -m pip install requests #不用找到模块文件位置用这个命令就可以安装了

 

两个序列化相关的模块(把python的字典、列表等转换成字符串

json

Json模块提供了四个功能:dumps、dump、loads、load

import json

dic = {‘k1‘:‘v1‘}
print(dic,type(dic))
#{‘k1‘: ‘v1‘} <class ‘dict‘>

r = json.dumps(dic)  #python基本数据类型转换成字符串形式
print(r,type(r))
#{"k1": "v1"} <class ‘str‘>

s1 = ‘{"k1":"123"}‘   #里面必须是双引号,外面必须是单引号 (其他语言单引号叫字符,双引号叫字符串)
r1 = json.loads(s1)   #将python字符串类型转换成基本数据类型
print(r1,type(r1))
#{‘k1‘: ‘123‘} <class ‘dict‘>


li = [11,22,33,]
json.dump(li,open(‘db‘,‘w‘))    #先序列化再写入db文件


li = json.load(open(‘db‘,‘r‘))   #先读文件再序列化出来
print(type(li),li)                     #<class ‘list‘> [11, 22, 33]
 

 

使用json做请求获得字符串转化成字典

import json
import requests

response = requests.get(‘http://wthrcdn.etouch.cn/weather_mini?city=北京‘)
response.encoding = ‘utf-8‘
dic1 = json.loads(response.text)
print(dic1)

 pickle

只能python使用

pickle模块提供了四个功能:dumps、dump、loads、load

li = [11,222,33,] 
r = pickle.dumps(li)
print(type(r),r)
#<class ‘bytes‘> b‘\\x80\\x03]q\\x00(K\\x0bK\\xdeK!e.‘

result = pickle.loads(r) #转化成列表
print(result)
#[11, 222, 33]

pickle.dump(li,open(‘123‘,‘wb‘))      #先序列化再写入文件
re = pickle.load(open(‘123‘,‘rb‘))     #读文件,序列化后输出

print(re)
#[11, 222, 33]

 两者区别与优缺点:

json 只能处理基本的数据类型,更加适合跨语言,字符串,如果是一个自己的写的类就不能转换

pickel 支持任何类型,适合对python的所有类型操作,仅适用于python,python版本不同可能会出现问题

 

time 模块 (http://www.cnblogs.com/alex3714/articles/5161349.html

常用

import time

print(time.time()) #1970年开始计时到现在的系统时间戳
#1465123123.342

print(time.ctime()) #当前时间
#Sun Jun  5 18:38:43 2016

print(time.ctime(time.time()-86400))
#Sat Jun  4 18:38:43 2016

print(time.gmtime())
#time.struct_time(tm_year=2016, tm_mon=6, tm_mday=5, tm_hour=10, tm_min=38, tm_sec=43, tm_wday=6, tm_yday=157, tm_isdst=0)

t_obj = time.gmtime()
print(t_obj.tm_year,t_obj.tm_mon,t_obj.tm_mday)
#2016 6 5

print(time.localtime())  #获取本地时间,本地用哪个时区就获取哪个时区的
#time.struct_time(tm_year=2016, tm_mon=6, tm_mday=5, tm_hour=18, tm_min=40, tm_sec=41, tm_wday=6, tm_yday=157, tm_isdst=0)


print(time.mktime(t_obj)) #把时间对象转成时间戳
#1465094462.0


time.sleep(4)
print("-------")

tm = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) #常用 将字符串格式转成格式化形式
print(tm)
#2016-06-05 18:41:27


tm1 = time.strptime("2016-05-6 15:06","%Y-%m-%d %H:%M")
print(tm1)
#time.struct_time(tm_year=2016, tm_mon=5, tm_mday=6, tm_hour=15, tm_min=6, tm_sec=0, tm_wday=4, tm_yday=127, tm_isdst=-1)

  datetime

常用

import datetime
print(datetime.date.today())
#2016-06-05

tm2 = datetime.datetime.now() # 现在的时间
print(tm2)
#2016-06-05 18:42:58.458000

print(datetime.datetime.now() + datetime.timedelta(days=10)) #比现在加10天
#2016-06-15 18:42:58.458000


current_time = datetime.datetime.now()
print(current_time.replace(2015,5))   #直接回到某个时间
#2015-05-05 18:42:58.458000


time_obj = current_time.replace(2015,5)
print(current_time==time_obj)

 time &datetime

import time
import datetime
 
print(time.clock()) #返回处理器时间,3.3开始已废弃
print(time.process_time()) #返回处理器时间,3.3开始已废弃
print(time.time()) #返回当前系统时间戳
print(time.ctime()) #输出Tue Jan 26 18:23:48 2016 ,当前系统时间
print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式
print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式
print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,但返回 的本地时间
print(time.mktime(time.localtime())) #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
#time.sleep(4) #sleep
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式
print(time.strptime("2016-01-28","%Y-%m-%d") ) #将字符串格式转换成struct_time格式
 
#datetime module
 
print(datetime.date.today()) #输出格式 2016-01-26
print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 将时间戳转成日期格式
current_time = datetime.datetime.now() #
print(current_time) #输出2016-01-26 19:04:30.335935
print(current_time.timetuple()) #返回struct_time格式
 
#datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
print(current_time.replace(2014,9,12)) #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换
 
str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式
new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天
new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天
new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时
new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s
print(new_date)

 

DirectiveMeaningNotes
%a Locale’s abbreviated weekday name.  
%A Locale’s full weekday name.  
%b Locale’s abbreviated month name.  
%B Locale’s full month name.  
%c Locale’s appropriate date and time representation.  
%d Day of the month as a decimal number [01,31].  
%H Hour (24-hour clock) as a decimal number [00,23].  
%I Hour (12-hour clock) as a decimal number [01,12].  
%j Day of the year as a decimal number [001,366].  
%m Month as a decimal number [01,12].  
%M Minute as a decimal number [00,59].  
%p Locale’s equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].  
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locale’s appropriate date representation.  
%X Locale’s appropriate time representation.  
%y Year without century as a decimal number [00,99].  
%Y Year with century as a decimal number.  
%z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].  
%Z Time zone name (no characters if no time zone exists).  
%% A literal ‘%‘ character.

 logging模块

 python的logging模块提供了标准的日志接口,通过它存储各种格式的日志,logging的日志可以分为 debug()info()warning()error() and critical() 5个级别

import logging
 
logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down")
 
#输出
WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:server is down

 

看一下这几个日志级别分别代表什么意思

LevelWhen it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL A serious error, indicating that the program itself may be unable to continue running.

 

 把日志写到文件里

import logging
 
logging.basicConfig(filename=‘example.log‘,level=logging.INFO)
logging.debug(‘This message should go to the log file‘)
logging.info(‘So should this‘)
logging.warning(‘And this, too‘)

  其中level=loggin.INFO意思是,把日志纪录级别设置为INFO,只有日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望记录debug的日志,那把日志级别改成DEBUG就行了。

 

给日志加上时间

import logging
logging.basicConfig(format=‘%(asctime)s %(message)s‘, datefmt=‘%m/%d/%Y %I:%M:%S %p‘)
logging.warning(‘is when this event was logged.‘)
 
#输出
12/12/2010 11:46:36 AM is when this event was logged.

 

同时把log打印在屏幕和文件日志里

 

 

 

 

 

 

以上是关于python 基础 day5的主要内容,如果未能解决你的问题,请参考以下文章

Day5 双层装饰器字符串格式化

python-day5-装饰器补充模块字符串格式化和序列化

Python自动化运维之路Day5基础篇

Day5 python装饰器

Python之路_Day5

python的学习之路day5