python的导包
python采用的导包方式有多种
如:import x(包名)
比如 导包时 import hashlib 调用时 hashlib.md5("123456".encode("utf-8"))
import x(包名).xxx(方法名)
比如导包时 import os.path 调用时 path.join(postion,i)
from x(包名) import xxx(方法名) as xx(别名)
比如导包时 from os import path as pth 调用时 pth.abspath("../")
from x(包名) import *
比如导包时 from package1 import * (package1是自定义的包) 调用时直接写函数名即可
注意这种方法在调用时 只有包内定义的__all__=['func1','func2']列表中存在该方法时 该方法才能调用
packag1包
__all__=['func1','func2','test']
def func1():
pass
def func2():
pass
def func3():
pass
class test():
def func4(self):
pass
def func5(self):
pass
可以看到func3不能直接被调用
python的copy
在py中想要对一个对象进行复制时
可以使用 = copy包中的copy方法 deepcopy方法
这三者的不同之处主要体现在
等号复制时相当于将对象的地址直接赋值给了新的变量
copy会将第一层的内容复制下来 二层的数据还是以地址的形式复制
deepcopy则会递归 将所有数据以数值的方式重写一份
下面举个例子
import copy
olist1 = [1, 2, 3, 4, 5, 6]
olist2 = [1, 2, 3, 4, 5, 6]
olist3 = [1, 2, 3, [7, 8, 9], 4, 5, 6]
olist4 = [1, 2, 3, [7, 8, 9], 4, 5, 6]
list1 = olist1
list2 = olist2.copy()
list3 = copy.copy(olist3)
list4 = copy.deepcopy(olist4)
print("等号:")
print("老列表变之前 老",olist1,"新",list1)
olist1.append(0)
print("老列表变之后 老",olist1,"新",list1)
print("新老列表都发生变化")
print("浅拷贝 ")
print("老列表变之前 老",olist2,"新",list2)
olist2.append(0)
print("老列表变之后 老",olist2,"新",list2)
print("老列表发送变化")
print("浅拷贝:")
print("老列表变之前 老",olist3,"新",list3)
olist3[3].append(0)
print("老列表变之后 老",olist3,"新",list3)
print("只copy一层 新老列表都变化")
print("深拷贝")
print("老列表变之前 老",olist4,"新",list4)
olist4[3].append(0)
print("老列表变之后 老",olist4,"新",list4)
print("copy多层 只有老列表变化")
结果如上
python的迭代器与可迭代对象
生成器可以生成可迭代对象 如列表 迭代器等
from collections.abc import Iterable, Iterator
ls=[i for i in range(10)]
print("是可迭代对象",isinstance(ls,Iterable))
print("是迭代器",isinstance(ls,Iterator))
print("列表 是一个可迭代对象 不是迭代器 可以将列表变成可迭代对象",ls)
nls=iter(ls)
print("是可迭代对象",isinstance(nls,Iterable))
print("是迭代器",isinstance(nls,Iterator))
print("将列表转化为迭代器 使用函数iter()",nls)
it=(i for i in range(10))
print("是可迭代对象",isinstance(it,Iterable))
print("是迭代器",isinstance(it,Iterator))
print("迭代器 是一个可迭代对象 同时也是一个迭代器",it)
print("""
======总结=====
迭代器可以使用 next关键字
迭代对象则可以使用 for来迭代
""")
使用函数生成器生成斐波那契列表:
from collections.abc import Iterator, Iterable
def fibonacci(n):
if n==0 or n==1: return 1
else:
return fibonacci(n-1)+fibonacci(n-2)
lis=[]
def fiblis(num):
for i in range(num):
lis.append(fibonacci(i))
def fibiter(num):
for i in range(num):
yield fibonacci(i)
fiblis(8)
print("值",lis,"是否为迭代器",isinstance(lis,Iterator),"是否为可迭代对象",isinstance(lis,Iterable))
iterator=fibiter(8)
print("值",iterator,"是否为迭代器",isinstance(iterator,Iterator),"是否为可迭代对象",isinstance(iterator,Iterable))
print(" 取出迭代器的值")
for i in iterator:
print(i,end=' ')
生成器也可以变成列表 使用list函数
函数闭包 装饰器
在函数调用时 默认是无法直接使用其它函数的值或方法的 在python中可以函数写到另一个函数的内部 内部的函数能调用外部函数的变量和方法 这样就叫做函数闭包
比如:
def func1(a, b):
print("func1")
c = a + b
print(f"func1 c value {c}")
def func2(d):
e = c + d
print(f"func2 e value {e}")
return e
return func2
ans=func1(1,2)
ans=ans(3)
print(ans)
在上述的闭包函数中外层函数的返回值为一个函数对象 内层函数的返回值 为e是c+d的结果 其中c又是外层函数的一个运算结果
当我以上述的形式调用函数时 func1返回一个函数对象func2且计算出c的值 为3 再调用func2计算出e将e返回给ans 运行结果如下
装饰器就是通过闭包函数来实现的 使用装饰器可以在不改变原有的代码的基础上添加或修改功能
比如实现用户的登录认证
from hashlib import md5
def check(login):
def to_check(username, password):
true = md5("root".encode("utf-8"))
true.update("salt".encode("utf-8"))
if username == "admin" and password == true.hexdigest():
login(username, password)
else:
print("error")
return to_check
@check
def login(username, password):
print(f"用户名{username}密码为{password}的用户 欢迎您")
user = input("输入用户名")
password = input("密码请输入")
password = md5(password.encode('utf-8'))
password.update("salt".encode('utf-8'))
login(user,password.hexdigest())
可以看到 我们定义了一个装饰器check来检测用户的输入是否为正确的输入 装饰器 调用时 首先将原有的函数传递给外层函数 装饰器函数继续运行 将内部的闭包函数传递给函数login并取代该函数