#!C:\Users\git.git-THINK\AppData\Local\Programs\Python
# -*- coding:utf-8 -*-
#1、函数的概念:有一个函数即变量的概念,要使用函数需要先定义,函数名相当于变量名,指向该函数的内存地址,在函数名后面加()就是调用该函数。
# def foo():
# print('Hello world')
#
# print(foo) # <function foo at 0x0000000000B5EF28>
# foo() # Hello world
#2、编码:在内存中都是一般都是unicode编码,如编写.py等word文件,编写时不会出现乱码格式,就是因为采用万国码。但同样可以在内存中转换编码格式
#encode方法:将万国码转换为utf-8编码格式,显示为16进制;decode方法反过来,将其转换为万国码。
#若要不乱码,需要文件存储和打开时采用相同的编码格式
# # -*- coding:utf-8 -*-标注的这句话就是告诉Python编辑器用什么编码格式打开文件,右下角的UTF-8表示存储时的编码格式。
#内存为了追求速度,所以采用万国码,牺牲了空间,硬盘在存储上不追求速度,所以采用压缩的utf-8(压缩是消耗时间和cpu的)
# s1 = '哈哈哈'
# print(s1.encode('utf-8')) #b'\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88'
# print(s1.encode('utf-8').decode('utf-8')) #哈哈哈
#3、文件操作
# with open('a.txt','w',encoding='utf-8') as f: #首先检测文件是否存在,不存在则创建,存在则将文件内容清空后重写
# f.write('哈哈哈')
# f.write('\nbbb')
# f.write('\nccc')
#
# with open('a.txt',mode = 'r',encoding='utf-8') as f: #读操作,若没有该文件会报错 FileNotFoundError
# f.read()
# f.seek(0) #0:光标在起始位置;2:光标在文件最后
# v = f.readline() #读取光标所在的那一行
# v2 = f.readlines() #将光标所在的后面的内容按行存放在列表中
# print(v,v2)
#
# with open('a.txt','a',encoding = 'utf-8') as f: # a:追加,打开这个文件之后直接定位到文件的末尾。
# f.write('bbb')
#同时还有一些组合,r+读写权限 w+写读权限 a+ 读写权限
#4、函数:内置函数和自定义函数
# 定义函数和函数的调用
#定义函数:只是检测函数的语法,不执行代码。
#函数的调用:先找到函数的名字,再根据函数的名字执行代码。若执行代码时未找到函数名会报错。所以先定义函数再调用。
#5、形参和实参:形参相当于是变量名,实参相当于变量值。形参只是作为一个值得传递,只有在函数调用的时候,将实参的值传递给形参,函数调用结束,形参和值解除绑定。
#6、位置形参:*args 命名关键字:**kwargs
#7、条件表达式
# def max_foo(x,y):
# return x if x > y else y #如果条件成立则返回左侧的值,如果条件不成立则返回右侧的值。
# print(max_foo(4,9))
#8、函数的默认值:定义是给形参赋值,
# def name_my(name,age=18):
# print(name,age)
# name_my('wangkc') #wangkc 18
#9、
# def foo(x,y,*args):
# print(x,y)
# print(args)
#
# foo(1,2,3,4,5) #(3, 4, 5)
# foo(1,2,[3,4,5]) #([3, 4, 5],) 后面的是作为一个元素,若要分开,每个值都要成为一个元素,需要在调用时前面加*,如下
# foo(1,2,*[3,4,5]) #(3, 4, 5) # 同 foo(1,2,3,4,5)
# def foo1(x,y,**kwargs):
# print(x,y)
# print(kwargs)
#
# foo1(1,2,a=123,b=456) #key = value 形式,注意这里的a、b就是参数不用引号。
# foo1(1,2,**{'a':123,'b':456}) #同foo1(1,2,a=123,b=456)
###############函数对象:函数是第一类对象,可以被当做数据一样被传递
#1、可以被引用
#2、可以当做参数传递
#3、返回值可以是函数
#4、可以当做容器类型元素
# def foo():
# print('from foo')
# func = foo
# print(func,foo) #一样的,都是打印的内存地址:function foo at 0x000000000050EF28> <function foo at 0x000000000050EF28
# foo() #from foo
# def foo():
# print('from foo')
#
# def bar(func): #函数名称作为参数名调用
# print(func) #这样直接在参数名后面加()就可以直接调用函数:function foo at 0x00000000007DEF28
# func()
#
# bar(foo) #from foo
#函数作为返回值
# def foo():
# print('from foo')
# def bar(func):
# return func
# f = bar(foo)
# print(f) #<function foo at 0x0000000000B8EF28>
# f() #from foo
#函数作为容器的参数
# def foo():
# print('from foo')
# dic1 = {'func':foo}
# print(dic1['func']) #<function foo at 0x0000000000B7EF28>
# dic1['func']() #from foo
##应用
# def insert(sql):
# print('新增')
# def delete(sql):
# print('删除')
# def update(sql):
# print('修改')
# def select(sql):
# print('查找')
#
# #新建一个字典,将上述函数作为其中的元素
# func_dict = {
# 'insert':insert,
# 'delete':delete,
# 'update':update,
# 'select':select
# }
#
# #main函数调用
# def main():
# while True:
# sql = input('请输入要执行的sql语句:').strip()
# if not sql : continue
# #对得到的sql语句分割
# l = sql.split()
# cmd = l[0]
# if cmd in func_dict:
# func_dict[cmd](l)
# main()
########################################名称空间与作用域##################
#1、定义名字的方法
# def foo():
# pass
# class als:
# pass
#2、3种名称空间
#内置名称空间:随着Python解释器的启动而启动,如print()方法,
# 等,这些方法都不需要定义,只要Python解释器启动,就可以使用
# a = max(1,2,3)
# print(a)
# import builtins
# for i in dir(builtins): #打印出是内置名称空间的参数
# print(i)
#全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间(在文件中定义后,在其后的文件中可以任意调用而不受作用域限制的
# x = 1
# if x ==1:
# y = 2
# import time
# print(y)
# def foo():
# pass
#局部名称空间:调用函数时会临时产生局部名称空间,只在函数调用时临时绑定,在函数调用结束后解绑定。
# x = 1000
# def foo1():
# x = 1
# def foo2():
# print(x)
# return foo2
# f= foo1() #返回的是foo2函数名
# print(f) #<function foo1.<locals>.foo2 at 0x0000000000739048>
# f() # 1
# print(x) #1000
#作用域:
#全局作用域:内置命名空间和全局命名空间
#局部作用域:局部命名空间
#执行时,名字查找顺序:局部名称空间--》全局名称空间--》内置名称空间 ,若是都找不到,就会报错
#查看全局作用域的名字:globals()
#查看局部作用域内的名字:locals()
# x = 100
# def foo():
# y = 3
# print(locals()) #{'y': 3}
# print(globals()) #{'x': 100, 'foo': <function foo at 0x0000000000B3EF28>,
# foo() #{'y': 3}
# print(locals()) #{'x': 100, 'foo': <function foo at 0x0000000000B3EF28>, 注意:在全局中打印局部得到的结果和全局的一样的,要得到哪个局部的名字,就要在相应的局部中打印locals()
#print(globals() is locals()) #True
######################################################################闭包函数:###############################################
#定义:1、内部函数
#2、包含对外部作用域而非全局作用域的引用
#闭包函数的应用
# x = 100
# def foo1():
# x = 1
# def foo2():
# print(x)
# return foo2
# f = foo1()
# print(f) #function foo1.<locals>.foo2 at 0x0000000000A68048
# f() # 1
# print(f.__closure__[0].cell_contents) #打印出闭包的数值,,,,1
####################################################装饰器####################
#1、装饰器:装饰别人的函数,修饰添加功能,
#2、装饰器可以是任何可调用对象,被装饰的也可以是任何可调用对象。
#为啥要用装饰器:开放封闭原则:对修改是开放的,对扩展是开放的
#装饰器就是为了在不修改被装饰对象的源代码及调用方式上的基础上,为其添加新功能。
# import time
# def timmer(func):
# def wrapper(*args,**kwargs): #方便给func传递参数
# start_time = time.time()
# reg=func(*args,**kwargs) #防止index有参数和返回值
# stop_time = time.time()
# print('time used %s' % (stop_time - start_time))
# return wrapper #写闭包函数时一定要注意return这里是返回该函数名,不是函数体,不要括号
#
# @timmer #相当于 timmer(index)
# def index():
# time.sleep(3)
# print('welcome to index')
# index()
# import time
# def foo1(func):
# def foo2(*args,**kwargs):
# start_time = time.time()
# reg = func(*args,**kwargs)
# stop_time = time.time()
# return reg
# return foo2
#
# @foo1
# def home(name):
# time.sleep(2)
# print("welcome to %s's home" % name)
# return name
# f = home('wangkc') #welcome to wangkc's home
# print(f) #wangkc
# import time
# def timmer(func):
# def wrapper(*args,**kwargs):
# start_time = time.time()
# reg = func(*args,**kwargs)
# stop_time = time.time()
# print('run time is %s' % (stop_time - start_time))
# return reg
# return wrapper
# #带参数的装饰器
# dic1 = {'name':None,'status':False}
# def auth1(driver = 'file'):
# def auth2(func):
# def weper(*args,**kwargs):
# if driver == 'file':
# if dic1['name'] and dic1['status']:
# reg=func(*args,**kwargs)
# return reg
# else:
# name = input('请输入姓名:')
# pwd = input('请输入密码')
# if name == 'wangkc' and pwd == '111111':
# dic1['name']='wangkc'
# dic1['status'] = True
# reg=func(*args,**kwargs)
# return reg
# else:
# print('登录错误')
# elif driver == 'Mysql':
# print('MySQL的认证')
# elif driver == 'ldap':
# print('ldap的认证')
# return weper
# return auth2
#
# @auth1(driver='file') #index() == auth1(auth_wrapper)
# @timmer #timmer(index) --> index()==timmer_wrapper
# def index():
# time.sleep(2)
# print('welcome to home page')
# @auth1(driver = 'file') #如果函数带参数,则这里也要带参数
# def home(name):
# print('%s welcome to home page' %name)
# #home('wangkc')
# index()
##########################################迭代器和迭代对象##########################
#可迭代对象:内置__iter__()方法的都是可迭代对象
#迭代器:对可迭代对象执行__iter__()方法得到的结果就是迭代器,迭代器对象有__next__()方法
# list1 = ['a','b','c']
# l = list1.__iter__()
# for i in list1:
# print(l.__next__()) #a b c
#若超出边界还执行__next__()方法,则#抛出异常:StopIteration
# i = {'a':1,'b':2,'c':3}.__iter__() #字典类的迭代器方法得到的是key值
# print(i.__next__()) #b
# print(i.__next__()) #a
# print(i.__next__()) #c
# print(i.__next__()) #抛出异常StopIteration
# 异常处理 try
# dic1 = {'a':1,'b':2,'c':3}
# i = dic1.__iter__()
# while True:
# try:
# key = i.__next__()
# print(key,dic1[key])
# except StopIteration:
# break
#由len(s) == s.__len__() 得到 iter(dic1) == dic1.__iter__()
# dic1 = {'a':1,'b':2,'c':3}
# f = iter(dic1)
# print(next(f)) #c
# with open('a.txt','r',encoding = 'utf-8') as f:
# f.read()
#如何判断是可迭代对象还是迭代器对象
# from collections import Iterable,Iterator
# print(isinstance('abc',Iterable)) #True
# print(isinstance(f,Iterable)) #True
# print(isinstance('abc',Iterator)) #False
# print(isinstance(f,Iterator)) #True
#迭代器的优缺点:
#优点:1、提供了一种不依赖于下标的迭代方式
# 2、迭代器本身而言更节省内存空间,逐条显示。
#缺点:1、不能获取可迭代对象的长度
# 2、不如序列类型取值灵活,一次性取值,并且只能往后取值,不能后退
# l = [1000,1,2,4]
# i = enumerate(l) #给每个元素前面生成一个数字,默认从0开始
# print(next(i)) #(0, 1000)
# l = [1000,1,2,4]
# i = iter(l)
# print(i)
# for item in i:
# print(item) # 1000 1, 2 4 打印出值
#f = open('a.txt',encoding='utf-8')
# for line in f.readlines():
# print(line)
# print(next(f))
# for line in f:
# print(line)
#只有文件是可迭代对象
#可迭代对象只有__iter__()方法,执行该方法得到迭代器对象
#迭代器对象有__iter__(),__next__()方法,对迭代器对象来说执行__iter__()方法,还是其本身。
####################################函数嵌套#############################
# def f1():
# def f2():
# print('from f2()')
# def f3():
# print('from f3()')
# f3()
# f2()
# f1()
#from f2() from f3()
#############################生成器函数
#生成器函数:只要函数体包含yield关键字,该函数就是生成器函数。生成器就是迭代器
# def foo():
# print('First')
# yield 1 #有值则返回值,无值则返回None
# print('Second')
# yield 2
# print('Third')
# yield 3
# print('Fourth')
# yield 4
# print('Fifth')
# print('abcdd')
# g=foo()
# print(next(g)) #迭代器g的执行进而触发函数的执行
# for i in foo():
# print(i)
# def cont(n):
# i = 0
# while i < n:
# print('Start')
# yield i
# i += 1
# print('End')
#
# g=cont(3)
# print(g) #generator object cont at 0x00000000006E2B48
# print(next(g))
# print(next(g))
# print(next(g))
##生成器:相当于为给个函数封装了一个__iter__() 和 __next__() 方法
## 每次遇到yield,函数都会暂停,下一次next会从上次暂停的位置继续执行,直到下次yield或者最后
#模拟 tail -f a.txt |grep 'python'
import time
# def tail(failpath):
# with open(failpath,encoding='utf-8') as f:
# f.seek(0,2)
# while True:
# line = f.readline().strip()
# if line:
# yield line
# else:
# time.sleep(1)
###################
# def tail(filepath):
# with open(filepath,encoding='utf-8') as f:
# f.seek(0,2)
# while True:
# line=f.readline().strip()
# if line:
# yield line
# else:
# time.sleep(0.2)
###################################################
# t = tail('a.txt') #yield相当于是有返回值,如果直接调用,没有任何结果
# print(t)
# for line in t:
# print(line)
# def grep(pattern,lines):
# for line in lines:
# if pattern in line:
# yield line
#
# g = grep('python',tail('a.txt'))
# print(g)
#
# for i in g:
# print(i)
# import time
# def timmer(func): #这里是要把需要装饰的函数名传递进来,方便后面调用。如果不传函数名而是直接调用,在调用的位置会报:RecursionError: maximum recursion depth exceeded while calling a Python object
# def wrapper(*args,**kwargs):
# time_start = time.time()
# res=func(*args,**kwargs) #1、这里要使用func传递进来的形参名。2、定义成这种形式是方便,不管被装饰的函数有无参数,有无返回值,程序运行都不会报错
# time_stop = time.time()
# time_run = time_stop - time_start
# print('run time is %s' % time_run)
# return wrapper
#
# @timmer
# def log(name):
# time.sleep(3)
# print('welcome %s to zhuang' % name)
#
#
# log('wangkc')
# import time
#
# def timmer(func):
# def wrapper(*args,**kwargs):
# print("----->from timmer_wrapper")
# start_time = time.time()
# reg = func(*args,**kwargs)
# stop_time = time.time()
# run_time = stop_time - start_time
# print('run time is %s' % run_time)
# return reg
# return wrapper
#
# login_user={'user':None,'status':False}
# def auth(driver = 'file'):
# def auth2(func):
# def wrapper(*args,**kwargs):
# print("---->from auth_wrapper")
# if driver == 'file':
# if login_user['user'] and login_user['status']:
# reg = func(*args,**kwargs)
# return reg
# else:
# name = input("输入姓名:")
# password = input("输入密码")
# if name == 'wangkc' and password == '123123':
# login_user['user'] = name
# login_user['status'] = True
# reg = func(*args,**kwargs)
# return reg
# else:
# print("账号或密码错误")
# elif driver == 'ldap':
# pass
# elif driver == 'MySQL':
# pass
# else:
# print("==========>未知的认证来源")
# return wrapper
# return auth2
#
# @auth()
# @timmer
# def index():
# time.sleep(2)
# print('hello world')
#
#
# index()