Python基础2

2020-12-13 04:38

阅读:586

标签:register   文档   dfs   alice   时间   排错   tom   重要   error   

Python基础2

函数 - 面向过程编程

初识函数

  • 函数 :函数是以功能为导向,一个函数封装一个功能,登录,注册,评论,文件操作等

  • 优点:减少代码重复,提高代码的可描述性

  • #获取任意一个字符串的元素的个数
    s1 = 'fdskjlgfdgfdjkslgdfjkjafdsajk'
    count = 0
    for i in s1:
        count += 1
    print(count)
    
    
    #获取列表的元素的个数
    l1 = [1, 2, 3]
    count = 0
    for i in l1:
        count += 1
    print(count)
    
    # 利用函数
    l1 = [1, 2, 3]
    def new_len():
        count = 0
        for i in l1:
            count += 1
          print(count)
    new_len()

函数的结构

  • def func() :

    ?? ??

    关键字 函数名 () 和:结构需要

    • 函数名 : 与变量名命名规范一致,一定具有可描述性

    • l1 = [1, 2, 3]
      def new_len():
          count = 0
          for i in l1:
              count += 1
              print(count)
      new_len()

函数的调用 ***

函数名() → 函数的执行者/函数的调用者, 出现几次,这个函数就执行几次

l1 = [1, 2, 3]
def new_len():
    count = 0
    for i in l1:
        count += 1
    print(count)

函数的执行写多少次,执行多少次。
new_len() # 函数名() 函数的执行者。调用者。
new_len()  # 函数名() 函数的执行者。
new_len()  # 函数名() 函数的执行者。
new_len()  # 函数名() 函数的执行者。
new_len()  # 函数名() 函数的执行者。

l1 = [1, 2, 3]
def new_len():
    count = 0
    for i in l1:
        count += 1
    print(count)

for i in range(10):
    print(111)
    
for i in range(3):
    new_len()

函数的返回值

  • 函数的返回值 - 返回给函数的执行者

  • #一个函数就是封装一个功能,这个功能一般都会有一个最终结果的,比如你写一个登录函数,最终登录成功与否是不是需要返回你一个结果?还有咱们是不是都用过len这个函数,他是获取一个对象的元素的总个数,最终肯定会返回一个元素个数这样的结果:
    s1 = 'abfdas'
    print(len(s1))  # 6
  • 函数中的return作用 :

  • 1.结束函数,后面的代码统统不执行,只能在函数中用
    2.给函数的执行者返回具体的值
  • l1 = [1, 2, 3]
    def new_len():
        print(111)
        print(222)
        if 1 == 1:
            return
        print(333)
        print(444)
    new_len()
    #结果
    111
    222 
  • 函数中如果没有return,或者程序中只有一个return,函数的执行者得到的是None

  • l1 = [1, 2, 3]
    def new_len():
        count = 0
        for i in l1:
            count += 1
        return
    print(new_len())
    # 结果 :    None
  • 函数中return后面是单个值,则返回这个值(值类型不改变)

  • def func():
        print(111)
        # return 100
        # return [1, 2, 3]
        return {'name': '哈哈'}
    ret = func()
    print(ret, type(ret))
    # 结果 :
    111
    {'name': '哈哈'} 
  • 函数中return后面是多个值,函数的执行者得到的是一个人元组

  • def func():
        print(111)
        return 1, '走你', [22, 33]
    ret = func()
    print(ret, type(ret))  # (1, '走你', [22, 33])
    
    
    def func():
        print(111)
        # return 1+1+2
        return 2 > 1 # 返回结果
    ret = func()
    print(ret)
    # 结果
    111
    True

函数的传参

  • 之前的函数都是写死的,现在引出函数的传参,使代码更简便

  • 函数的传参 - - 函数的拓展性

  • def new_len(a):  # 定义函数时:参数:形参。
        count = 0
        for i in a:
            count += 1
        return count
    l1 = [1, 2, 3]
    print(new_len(l1)) # 函数的调用者:参数 实参。

    实参角度 :

    1. 位置参数
    # 1. 位置参数。: 从左至右,按照顺序,一一对应
    def meet(sex,age,job,):
        print('左划一下')
        print('右划一下')
        print(f'寻找性别{sex},年龄{age}岁,{job}')
    
    meet('女','18~25','讲师')
    
    #写一个函数,接收两个数字的参数,将较大的数字返回。
    def comp(a,b):
        if a > b:
            return a
        else:
            return b
    ret = comp(1,2000)
    print(ret)

    三元运算符:简单的if else。

    a1 = 1
    b2 = 2
    ret = a1 if a1 > b2 else b2
    print(ret)
    
    def comp(a,b):
        # ret = a if a > b else b
        # return ret
        return a if a > b else b
    ret = comp(1,2000)
    print(ret)
    2. 关键字参数

    ? 参数要一一对应

    def meet(sex,age,job,hight,weight,):
        print('左划一下')
        print('右划一下')
        print(f'寻找性别{sex},年龄{age}岁,身高{hight},体重{weight},工作{job}')
    
    meet(sex='女',job='学生',weight=120,hight=170,age='18~25')
    3.混合参数

    ? 关键字参数一定要在位置参数后面,遵循一一对应

    def meet(sex,age,job,hight,weight,):
        print('左划一下')
        print('右划一下')
        print(f'寻找性别{sex},年龄{age}岁,身高{hight},体重{weight},工作{job}')
    
    meet('男',22,'ITC语言',weight=120,hight=175,)

    形参角度 :

    • 1.位置参数 : 与实参角度位置参数一样

    • def meet(sex,age,job):
          print('左划一下')
          print('右划一下')
          print(f'寻找性别{sex},年龄{age}岁,{job}')
      
      meet('女','18~25','幼师')
    • 2.默认参数 : 一定要写在位置参数后面 , 不传参即沿用默认参数

    • # open('文件的改',encoding='utf-8')
      def meet(age,job,sex='女'):
          print('左划一下')
          print('右划一下')
          print(f'寻找性别{sex},年龄{age}岁,{job}')
      
      # meet('18~25','幼师')
      # 更改默认参数
      # meet('18~25','幼师',sex='laddy_boy')
      meet('18~25','幼师','laddy_boy')

    万能参数

    ? 形参角度 : 第三种传参方式 → 万能参数py

    def eat(food1,food2,food3):
        print(f'我请你吃:{food1},{food2},{food3}')
    eat('蒸羊羔','蒸熊掌','蒸鹿尾')
    #当给函数传入的参数数目不定时,之前的传参方式解决不了问题。
    
    万能参数 - 动态参数 :
    • *args
    def eat(*args):  # 将实参角度:定义一个函数时,* 所有的位置参数聚合到一个元组中。
        print(args)
        print(f'我请你吃:{args}')
    eat('蒸羊羔','蒸熊掌','蒸鹿尾','烧花鸭','烧企鹅')
    # 结果
    ('蒸羊羔', '蒸熊掌', '蒸鹿尾', '烧花鸭', '烧企鹅')
    我请你吃:('蒸羊羔', '蒸熊掌', '蒸鹿尾', '烧花鸭', '烧企鹅')
    
    # 函数接收不定个数的数字实参,将最终的和返回出去。
    def sum1(*args):
        # print(args)  (100, 2, 67, 3)
        result = 0
        for i in args:
            result += i
        return result
    print(sum1(100,2,67,3))
    # 结果 :172
    
    • ** kwargs
    def func(**kwargs):  # 函数的定义时:**将实参角度所有的关键字参数聚合成了一个字典,给了kwargs.
        print(kwargs)
    func(name='alex',age=84,hobby='唱跳rap篮球')
    # 结果 :{'name': 'alex', 'age': 84, 'hobby': '唱跳rap篮球'}
    
    • 万能参数
    # *args,**kwargs 万能参数
    def func(*args,**kwargs):
        print(args,kwargs)
    func(1,2,4,'fjdksal',age=84,hobby='唱跳rap篮球')
    # 结果 :(1, 2, 4, 'fjdksal') {'age': 84, 'hobby': '唱跳rap篮球'}
    
    • *的魔性用法(函数中)
    def func(*args,**kwargs):
        print(args)  
        print(kwargs)
    l1 = [1, 2, 3]
    l2 = ['太阳', 'moon', '云朵']
    func(l1,l2)
    # 结果:
    ([1, 2, 3], ['太阳', 'moon', '云朵'])
    {}
    
    func(*l1,*l2)  # 当函数的执行时:*iterable 代表打散。
    # 结果 :
    (1, 2, 3, '太阳', 'moon', '云朵')
    {}
    
    func(*[1, 2, 3],*(11,22),*'fdsakl')  # 当函数的执行时:*iterable 代表打散。
    # 结果:
    (1, 2, 3, 11, 22, 'f', 'd', 's', 'a', 'k', 'l')
    {}
    
    # 当函数的执行时:**dict 代表打散。
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    func(**{'name':"alex"},**{'age': 73,'hobby': '吹'})
    # 结果 :
    ()
    {'name': 'alex', 'age': 73, 'hobby': '吹'}
    
    • 函数外: 处理剩余元素

    • a,b,*c = [1,2,3,4,5]
      print(a,b,c) #  1 2 [3, 4, 5]
      
      a,*c,b, = [1,2,3,4,5]
      print(a,b,c) # 1 5 [2, 3, 4]
      
      a,*c = range(5)
      print(a,c) #  0 [1, 2, 3, 4]
      
      a,*c,b = (1,2,3,4,5,6)
      print(a,c,b) # 1 [2, 3, 4, 5] 6
      
    • *args的位置

      • *args不能放在位置参数前面,a,b取不到值

        def func(*args,a,b,sex='man',):
            print(a)
            print(b)
            print(sex)
            print(args)
            # print(kwargs)
        func(1,2,4,5,6) # 报错
        
      • *args如果想要接收到值之前,肯定要改变sex默认参数。

        def func(a,b,sex='man',*args):
            print(a)
            print(b)
            print(sex)
            print(args)
        func(1,2,4,5,6)
        # 结果:
        1
        2
        4
        (5, 6)
        
        
        def func(a,b,*args,sex='man'):
            print(a)
            print(b)
            print(sex)
            print(args)
        func(1,2,4,5,6)
        # 结果 :
        1
        2
        man
        (4, 5, 6)
        func(1,2,4,5,6,sex='women')
        # 结果 :
        1
        2
        women
        (4, 5, 6)
        
        **kwargs

        含参函数的形参位置 :

        位置参数 → *args → 默认参数 → 仅限关键字参数 → **kwargs

        def func(a,b,*args,sex='man',**kwargs,):
            print(a)
            print(b)
            print(sex)
            print(args)
            print(kwargs)
        func(1,2,4,5,6,name='星星',age=18)
        # 结果 :
        1
        2
        man
        (4, 5, 6)
        {'name': '星星', 'age': 18}
        

        形参角度第四种传参方式:仅限关键字参数

        # 位置参数,*args,默认参数,仅限关键字参数,**kwargs
        def func(a,b,*args,sex='man',c,**kwargs,):
            print(a)
            print(b)
            print(sex)
            print(c)
            print(args)
            print(kwargs)
        func(1,2,4,5,6,67,c=666,name='阿坤',age=18,)
        # 结果:
        1
        2
        man
        666
        (4, 5, 6, 67)
        {'name': '阿坤', 'age': 18}
        
        简单了解时间模块
        import time #导入时间模块
        print(time.time()) # time.time 为时间戳
        print(111)
        time.sleep(1) # 让程序静止1秒
        age = 18
        print(age)从空间角度研究函数
        

从空间角度研究函数

#变量 (函数名也叫变量)

input = 666
print(input)
# 从全局寻找input ————> 全局名称空间 ——————> 内置

input = '太白'
def func():
    #input = 666
    print(input)
func()
#从局部寻找input ——————> 局部名称空间 ————> 全局名称空间 ——————> 内置
# 取值顺序:单向不可逆

def func():
    name = 'moon'
func()
print(name) #全局找name --> 内置(不会在局部找)


name = '阿坤'
def func():
    #name = 'moon'
    def inner():
        print(name) # 先在局部找,如果局部没有,去全局找,然后内置
    inner()
func()

内置函数的研究 globals locals

name = 'moon'
l1 = [1, 2, 3]

def func():
    age = '18'
func()
print(globals()) # 全局作用域所有的内容
print(locals())  # 当前位置

三个小练习

# 例1:

# def func1():
#     print('in func1')
#     print(3)
# def func2():
#     print('in func2')
#     print(4)
#
# func1()
# print(1)
# func2()
# print(2)
'''
in func1
3
1
in func2'
4
2
---------------------------------------------
# 例2:
def func1():
    print('in func1')
    print(3)
def func2():
    print('in func2')
    func1()
    print(4)
print(1)
func2()
print(2)

'''
1
in func2
in func1
3
4
2
-----------------------------------------------
# # 例3:
#
def fun2():
    print(2)
    def func3():
        print(6)
    print(4)
    func3()
    print(8)

print(3)
fun2()
print(5)
#//3 2 4 6 8 5

关键字

count = 0
def func():
    count += 1
func()
# UnboundLocalError: local variable 'count' referenced before assignment
# 解释器认为:如果你在局部作用域对一个变量进行修改了,解释器认为你在局部作用域已经定义好这个变量了。但现在你并没有定义这个变量,所有报错了

1. 在局部作用域声明一个全局变量 : global - (剪切)

def func():
    global name
    name = 1
    print(globals())
    # print(locals())
    name += 1
    print(globals())
func()
# print(name)
print(globals())

2. global - 可以修改全局变量

count = 0
def func():
    global count
    count += 1
print(count)
func()
print(count)

3. 在局部作用域声明一个局部变量 - nonlocal - (复制)** - - → 不能操作全局变量

# nonlocal可以对父级作用域的变量进行修改,并且在当前作用域创建(复制)一份此变量。
def func():
    count = 0
    def inner():
        nonlocal count
        count += 1
        print(count)
        print(locals())
    inner()
    print(locals())
func()
#UnboundLocalError: local variable 'count' referenced before assignment
#解释器认为:如果你在局部作用域对一个变量进行修改了,
#你在局部作用域已经定义好这个变量了。

4. 默认参数的坑

def func(a,b=False):
    print(a)
    print(b)
func(1,True)
#当你的默认参数如果是可变的数据类型,你要小心了。
#?
def func(a,l=[]):
    l.append(a)
    return l
print(func(1))  # [1,]
print(func(2))  # [1,2]
print(func(3))  # [1,2,3]

函数名的应用

1. 函数名指向的是函数的内存地址,加上()就执行这个函数 : → func()

函数名是一个特殊的变量。
def func():
    print(666)
print(func)  # func = 

2. 函数名是一个变量。

def func():
    print(666)
f1 = func
f2 = f1
f2()
f1()

3. 函数名可以作为容器类类型的元素。

def func1():
    print('in func1')
def func2():
    print('in func2')
def func3():
    print('in func3')
l = [func1, func2, func3]
print(l)
for i in l:
    i()
# 结果:
[, , ]
in func1
in func2
in func3

4. 函数名可以作为函数的实参。

a = 1
def func(argv):
    print(argv)
func(a)


def func1():
    print('in func1')
def func2(argv):
    argv()
    print('in func2')
func2(func1)

5. 函数名可以作为函数的返回值。

b = 666
def func1():
    print('in func1')
def func2(argv):
    print('in func2')
    return argv
ret = func2(b)
print(ret)


def func1():
    print('in func1')
def func2(argv):
    # argv = func1 : function 43543
    print('in func2')
    return argv
ret = func2(func1)  # func1 : function 43543
ret()



def wrapper():
    def inner():
        print(666)
    return inner
# ret = wrapper()
# ret()
wrapper()()

格式化输出f

#f不区分大小写
num = input('>>>')
s = F'python{num}'
print(s)


#可以加入表达式
s1 = 'moon'
s2 = f'我的名字{s1.upper()}'
print(s2)


l1 = ['阿坤', 18, 176]
s1 = f'我的名字{l1[0]},我的年龄{l1[1]},我的身高{l1[2]}'
print(s1)


#可以结合函数
def func(a,b):
    return a + b
s1 = f'最终的结果{func(1,3)}'
print(s1)


#不能放一些特殊的字符 ! , : { } ;
print(f"替换结果{{{73}}}")
print(f'{12,}')

可迭代对象

# 字面意思分析 : 可以重复的迭代的实实在在的东西
# list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄
# 专业角度:内部含有'__iter__'方法的对象,就是可迭代对象.
# 内置函数 :dir()   print(dir(str))
# 判断一个对象是不是可迭代对象 : print('__iter__' in dir(str))
# 优点:
            1.直观    2.操作方法较多
# 缺点:
            1.占内存   2.不能迭代取值(索引,字典的key)

1. 判断迭代对象

# str  list
# 内置函数:dir()→ 用来查方法
print(dir(str)) # 返回的表中有'__iter__' 就是可迭代对象

print('__iter__' in dir(str)) # True

2. 迭代器

# 字面意思 :可以重复迭代的工具
# 专业角度 : 内部含有'__iter__'并且'__next__'方法的对象,就是迭代器
# 优点 :
            1. 非常节省内存.  2.惰性机制
# 缺点 :
            1.不直观   2.操作不灵活 3.效率相对低
# 特性
l1 = [22, 33, 44, 55, 66, 77]
obj = iter(l1)
for i in range(3):
    print(next(obj))
for i in range(2):
    print(next(obj))

 
# 可迭代对象与迭代器的对比:
#       可迭代对象:可迭代对象是一个操作比较灵活,直观,效率相对高,但是比较占用内存的数据集。
#       迭代器:迭代器是一个非常节省内存,满足惰性机制,但是效率相对低,操作不灵活的数据集。

利用while循环,模拟for循环内部循环可迭代对象的机制。

#    先要将可迭代对象转化成迭代器。
#    利用next对迭代器进行取值。
#    利用异常处理try一下防止报错。
s = 'gkffdsa;lfkdsk;lafkds;laldgjfd'
obj = iter(s)
while 1:
     try:
         print(next(obj))
     except StopIteration:
         break
with open('调试',encoding='utf-8',mode='w') as f1:
    print(f1)
print(zip('fdsa','fdsagdfsg'))  # 
# 将zip函数中的两个可迭代对象参数按对应索引值进行匹配组合,得到zip对象。(拉链式函数)

3. 可迭代对象转化成迭代器 iter()

l1 = [1, 2, 3, 4, 5]
# 内置函数iter()
obj = iter(l1)  # l1.__iter__()
print(obj)  # 

4. 迭代器可以迭代取值。利用next()进行取值

l1 = [1, 2, 3, 4, 5]
# 内置函数iter()
obj = iter(l1)
print(obj)  #
print(next(obj)) # 1
print(next(obj)) # 2
print(next(obj)) # 3
print(next(obj)) # 4
...
#迭代器一条路走到底,不走回头(记录位置)。
# next超过元素会报错
for i in range(3):
    print(next(obj))
    
for i in range(2):
    print(next(obj))

生成器

1. 生成器函数 yield

def func():
    print(111)
    return 2
ret = func()
print(ret)
# 结果 :
111
2
# 执行此函数,遇到return结束函数。
# 将数字2返回给ret。
def func():
  print(111)
  yield 222
  yield 333
func()
# 结果 : 无


def func():
  print(111)
  yield 222
  yield 333
  yield 2,3,4
ret = func()
print(next(ret)
print(next(ret)   
print(next(ret)
print(next(ret)   
# 结果:
111
222
333
(2,3,4)
5.0
++++++++++++++++++++++++++++++++     
++++++++++++++++++++++++++++++++
# 01
a = 5
def func():
    global a
    a = 1
    yield 1
func()
print(a)
# 结果 :5
============================
# 02
a = 5
def func():
    global a
    a = 1
    yield 1
func()
print(next(func()))
print(a)
# 结果 :
1
1
============================
# 03
def func():
    yield 1
    print('哈哈')
func()
# 结果 :空

# 总结 : 在带有yield的函数中,若没有执行next(),则yield前后都不会执行

与迭代器一样,当程序运行完最后一个yield,再次运行next(),程序会报错

说明一个yield对应一个next,next超过yield数量,就会报错

# 只要函数中出现了yield那么他就不是函数,它是生成器函数。
# 一个next对应一个yield.
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))

# return yield
# return 结束函数,给函数的执行者返回值(多个值通过元组的形式返回)。
# yield  不结束函数,对应着给next返回值(多个值通过元组的形式返回)。

yield与return的区别:

  • return一般在函数中设置一个,,他的作用是终止函数,并且给函数的执行者返回值
  • yield在生成器函数中可设置多个,且并不会终止函数,next会获取对应yield生成的元素
# 举例说明:
def eat_baozi():
    list1 = []
    for i in range(1,2001):
        list1.append(f'{i}号包子')
    return list1
print(eat_baozi())

def eat_baozi_gen():
    for i in range(1,2001):
        # print(11)
        yield f'{i}号包子'
ret = eat_baozi_gen()  #这是一个生成器
print(ret)
# 结果 :
print(next(ret))  # 生成器,可以用next()函数一个一个打印出来
print(next(ret))
# 结果
1号包子
2号包子


#下一次打印的包子序号会接着上一次打印,也就是说,生成器会停留在最后一次打印(取出)元素的位置上
ret = eat_baozi_gen()
for i in range(200):
    print(next(ret))
for i in range(200):
    print(next(ret))
def func():
    l1 = [1, 2, 3]
    yield l1
ret = func()
print(next(ret))
print(next(ret))
print(next(ret))
因为函数中yield只有一个,而next()有多个,所有会报错

yield from :

可以直接把迭代对象中的每一个数据作为生成器的结果进行返回

def func():
    l1 = ['one', 'two', 'three']
    yield from l1
    yield 1
    yield 2
    yield 3
ret = func()
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))
"""
结果:
one
two
three
1
2
"""
# yield : 对应next给next返回值
# yield from 将一个可迭代对象的每一个元素返回给next
# yield from 节省代码,提升效率(代替了for循环)

2. 推导式

1. 列表推导式

l1 = [1,2,3......100]
l1 = []
for i in range(1,101):
    l1.append(i)
print(l1)

# 列表推导式
l1 = [i for i in range(1, 101)]
print(l1)

列表推导式的两种构建方式

# 1.循环模式: [变量(加工后的变量) for 变量 in iterable]
# 2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]
    1. 循环模式 :

      # 将10以内所有整数的平方写入列表。
      print([i**2 for i in range(1, 11)])
      
      # 100以内所有的偶数写入列表.
      print([i for i in range(2, 101, 2)])
      
      # 从python1期到python100期写入列表list
      print([f'python{i}期' for i in range(1, 101)])
      
    1. 筛选模式 :

      #一百以内大于49的数的列表
      print([i for i in range(1, 101) if i > 49])
      
      # 三十以内可以被三整除的数。(列表)
      print([i for i in range(1, 31) if i % 3 == 0])
      
      # 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
      l1 = ['barry', 'fdsaf', 'alex', 'sb', 'ab']
      print([i.upper() for i in l1 if len(i) > 3])
      
      # 找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
      names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
               ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
      l1 = []
      for i in names:
          for j in i:
              if j.count('e') > 1:
                  l1.append(j)
      print(l1)
      
      print([j for i in names for j in i if j.count('e') > 1])
      
  • 列表推导式的优缺点:
# 优点:
    # 1, 简单,快捷,装b。
# 缺点:
    # 2. 可读性不高,不好排错。

# 慎用,不要入迷。

2. 生成器表达式

# 生成器表达式:
# 与列表推导式几乎一模一样。
# 循环模式,筛选模式。

obj = (i for i in range(1, 11))
print(obj)
print(next(obj))
print(next(obj))
print(next(obj))
# # 如何触发生成器(迭代器)取值?
# # 1. next(obj)
# # 2. for 循环
# # for i in obj:
# #     print(i)
# # 3. 数据转化
# print(list(obj))

# 生成器表达式:生成器 节省内存。
# 字典推导式,集合推导式:  两种模式: 循环模式,筛选模式

l1 = ['小潘', '怼怼哥','西门大官人', '小泽ml亚']
# {0: '小潘', 1: '怼怼哥', 2: '西门大官人'}
dic = {}
for index in range(len(l1)):
    dic[index] = l1[index]
 print(dic)
# {0: '小潘', 1: '怼怼哥', 2: '西门大官人'}

print({i:l1[i] for i in range(len(l1))})
# {0: '小潘', 1: '怼怼哥', 2: '西门大官人'}


# 1~100
print({i for i in range(1, 101)})

匿名函数

匿名函数只能构建简单的函数,一句话函数 一般与lambda配合使用

def func(x,y):
    return x + y
# print(func(1, 2))

# 匿名函数构建
func2 = lambda x,y: x + y
print(func2(1, 2))

# 匿名函数最常用的就是与内置函数结合使用。

# 写匿名函数:接收一个可切片的数据,返回索引为 0与2的对应的元素(元组形式)。
func = lambda x: (x[0],x[2])
print(func('太白金星'))

# 写匿名函数:接收两个int参数,将较大的数据返回。
func1 = lambda x, y: x if x > y else y
print(func1(100,2))

func2 = lambda : 3
print(func2()) # 3
函数:
# str() dir() range() len() print() max() min() open()
# input() type() int() enumerate() list() id() set() dict()
# iter() next() tuple() bool() globals() locals() frozenset()

内置函数

# eval exce     慎用

eval:
s1 = "{1: 'alex'}"  →  eval(s1) 输出结果 :{1: 'alex'}
s2 = '1 + 3'    →eval(s2) 输出结果 :4 
eval 剥去字符串的外衣,返回里面的本质
# 前提条件 是字符串(str)
    若字符串里面的是数字,且里面有运算,则会直接输出结果
    
    
# exec 执行字符串类型的代码,(执行str里面的可执行代码)

s3 = '''
    for i in range(3):
         print(i)
     '''
exec(s3)
# 结果 : 执行s3里面的for循环,打印:0 1 2
# hash() 获取一个可哈希对象(int ,str ,bool,tuple..)的值
print(hash(123214134))
print(hash('fkljdsaklgjdfs'))
print(hash('gjdfs'))
# help() 查看函数或模块用途的详细说明
print(help(str.count))
# callable  ** 用于查看一个人对象是否可调用,若返回True,程序可能会报错,但是返回False.肯定会失败
name = 'alex'
def func():
    pass
print(callable(name))  # False
print(callable(func))  # True
# int  ** 用于将一个字符串或数字转化为整型
print(int(3.14))
print(int('123'))
print(float(100)) # 将整数和字符串转换成浮点数
print(complex(1,2)) #函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。。
print(bin(100))  # 将十进制转化成二进制。 **
print(oct(10)) # 将十进制转化成八进制字符串并返回。
print(hex(17)) # 将十进制转化成十六进制字符串并返回。 **

# 将其他进制转换成10进制:
print(int('1010',2))
print(int('12',8))
print(int('a',16))

print(divmod(10, 3)) # 结果:(5, 0)  **
# 计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)分页用到
print(round(3.1485926,2)) #结果 :print(round(3.1485926,2))
# 保留小数的有效位置 默认保留整数,保留遵循四舍五入原则
print(pow(3, 3))  # 求x的y次幂.(三个参数为x**y的结果对z取余)
print(pow(3, 3, 2))
print(ord('a')) # 输入字符寻找其在unicode的位置。
print(ord('中'))
print(chr(98))  # **  # 输入位置数字找出其对应的字符
print(chr(20104))  # 予
print(repr('太白'))  #  结果 :'太白'   repr 原形毕露  **
l1 = [1, 'fgdsa', [], {1: 2}]
l2 = [0, '', [], {}]
print(all(l1)) # 判断可迭代对象元素全部都为True,返回True
print(any(l2))  # 判断可迭代对象元素只要有一个True返回True
sep # 设定分割符。
end # 默认是换行可以打印到一行
print(1, 2, 3, sep='|')
print(1, 2, end=' ')
print(3, 4)
f = open('log','w',encoding='utf-8')
 # f.write('写入文件')
print('写入文件', file=f)
list
# l1 = list('fdsafd')
# print(l1)
dict
# 创建字典的几种方式
dic = {1: 2}
dic = dict(one=1, two=2, three=3)
dic = dict.fromkeys(可迭代对象,每一个key的值)
print({i: 1 for i in range(3)})
# 字典推导式
print({i: 1 for i in range(3)})
# abs()  获取绝对值
print(abs(-10))
# sum() 数字相加求和
# sum(iterable,)
print(sum([1,2,3,4]))
print(sum([1, 2, 3, 4], 100)) # 结果 : 110


#####  非常非常非常重要的  #####

# min 可以加功能
print(min([22, 11, 45, 2]))  # 结果 : 2

#找年龄最小的元组
l1 = [(73, 'alex'), (35, '武大'), (18, '太白')]
print(min(l1)) #返回的是这个组成列表的元组  (18, '太白')

l1 = [('alex', 73, 170), ('太白', 18, 185), ('武大', 35, 159),]
# # 通过设置key去使用min
# # key = 函数名
# # def func(x):  # x = ('alex', 73)
# #     return x[1]

# # 返回值是什么就按照什么比较最小的。

# # min 会自动的将可迭代对象的每一个元素作为实参传给x,
'''
第一次,x = ('alex', 73)   73
第二次,x = ('武大', 35)   35
第三次,x = ('太白', 18)   18
'''

# 将遍历的那个元素即是 ('太白', 18) 返回
# print(min(l1,key=func))
# print(min(l1,key=lambda x: x[1]))


# def func(x):
#     return x[1]
# print(min(l1,key=func))
# print(min(l1,key=lambda x: x[1]))
# print(min(l1,key=lambda x: x[2])[0])
# 练习:
dic = {'a':3,'b':2,'c':1}
# 将dic值最小的键返回。
print(min(dic,key= lambda x:dic[x]))
# 将dic值最小的值返回。
# print(dic[min(dic,key= lambda x:dic[x])])
dic = {'A':['李业', 67],'b': ['怼哥', 95],'c': ['冯垚', 85]}
# 将成绩最低的从属于的那个列表返回。
print(dic[min(dic,key=lambda x:dic[x][1])])
# 将成绩最低的分数返回。
print(dic[min(dic,key=lambda x:dic[x][1])][1])


# max() 与min 用法相同。


# reversed()  对一个可迭代对象进行翻转,返回一个迭代器
s1 = 'alex'
print(reversed(s1)) #// 
for i in reversed(s1):
    print(i)
# 结果 :
x
e
l
a

# 内置函数:bytes()
s1 = '太白'
# 方法一:
print(s1.encode('utf-8')) #  b'\xe5\xa4\xaa\xe7\x99\xbd'
# 方法二:
print(bytes(s1,encoding='utf-8')) #  b'\xe5\xa4\xaa\xe7\x99\xbd'


# 解码:
b1 = b'\xe5\xa4\xaa\xe7\x99\xbd'
# 方法一:
print(b1.decode('utf-8'))
# 方法二:
 print(str(b1, encoding='utf-8'))
# 继续min()

dic = {'c': 1, 'b': 2, 'a': 3}
# 最小的值对应的键返回
print(min(dic))
print(min(dic,key=lambda x:dic[x]))
# min 会自动将dic的每个key依次传给x,返回值设定什么,就按照什么比较大小。
# 最后将x返回。
# 最小的值对应的值返回
print(dic[min(dic, key=lambda x:dic[x])])

list = [
    {'name': 'alex', 'age': 73},
    {'name': 'wusir', 'age': 35},
    {'name': '太白', 'age': 25},
 ]
# 将年龄最小的 字典返回。
print(min(list,key=lambda x: x['age']))
# 将年龄最小的名字返回。
print(min(list,key=lambda x:x['age'])['name'])
# 将年龄最小的年龄返回。
print(min(list,key=lambda x: x['age'])['age'])

# zip 拉链方法 返回一个迭代器
#函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,
#然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回,
l1 = [1, 2, 3, 4]
tu = ('a', 'b', 'c')
s = 'python23'
# # print(zip(l1,tu,s))
print(list(zip(l1,tu,s)))
#结果 :[(1, 'a', 'p'), (2, 'b', 'y'), (3, 'c', 't')]

# sorted 排序
l1 = [2, 6, 4, 1, 3]
# 列表原有的方法
l1.sort()
print(l1)
# 形成新列表
print(sorted(l1))
print(l1)

list1 = [
    {'name': 'alex', 'age': 73},
    {'name': 'wusir', 'age': 35},
    {'name': '太白', 'age': 25},
]
# 加key
print(sorted(list1))
print(sorted(list1, key=lambda x:x['age']))
print(sorted(list1, key=lambda x:x['age'],reverse=True))
#
l1 = [('张一东', 80), ('张耳洞', 75), ('怼怼哥', 7), ('李业', 59)]
print(sorted(l1,key=lambda x:x[1]))
print(sorted(l1,key=lambda x:x[1],reverse=True))

# filter  返回一个生成器
# 生成器表达式的筛选模式
l1 = [56, 67, 12, 34, 78, 90,]
print([i for i in l1 if i > 60])
# 返回值为True的留下来
print(filter(lambda x: x>60,l1)) # 
print(list(filter(lambda x: x>60,l1)))# [67, 78, 90]
#
lst = [{'id':1,'name':'alex','age':50},
       {'id':1,'name':'wusir','age':17},
        {'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:x['age']

闭包

什么是闭包:
    闭包是存在嵌套函数当中的,内层函数对外层函数的非全局变量的引用,这样就会产生闭包,引用的变量也就是自由变量,不会随着函数的结束而消失,会一直保存在内存中,最终的目的就是保证了数据的安全
闭包的形成条件:
    1.闭包存在于嵌套函数中
    2.内存函数对外层非全局变量引用(改变)
    (参考函数名逐层返回直至返回到最外层)
闭包:
    闭包函数的空间不会随着函数的结束而消失
    被引用的变量也不会消失
    被引用的变量叫自由变量
# 第一版: 没有保证数据的安全
l1 = []  #全局变量
def make_average(price):
    l1.append(price)
    total = sum(l1)
     return total/len(l1)
print(make_average(100000))
print(make_average(110000))
print(make_average(120000))

# 有很多代码....

# l1.append(666) 不小心输入个append就会是数据不准确
# print(make_average(90000))



# 第二版:
# 每次执行l1是空的。
def make_average(price):
    l1 = []
    l1.append(price)
    total = sum(l1)
    return total/len(l1)
print(make_average(100000))
print(make_average(110000))
print(make_average(120000))

# 为了保证数据的安全,闭包
def make_average():
    l1 = []
    def average(price):
        l1.append(price)
        total = sum(l1)
        return total/len(l1)
    return average
avg = make_average()
# print(avg)
print(avg(100000))
print(avg(110000))
print(avg(120000))
# print(globals())

def make_average():
     count = 1
    def average():
        nonlocal count
        count += 1
        return count
    return average
avg = make_average()
print(avg)
print(avg())
print(avg())
print(avg())
print(avg())





# 例一:
def wrapper():
    a = 1
    def inner():
        print(a)
    return inner
ret = wrapper()

# 例二:
a = 2
def wrapper():
    def inner():
        print(a)
    return inner
ret = wrapper()

# 例三:
def wrapper(a,b):
    def inner():
        print(a)
        print(b)
    return inner
a = 2
b = 3
ret = wrapper(a, b)

# 判断一个函数是不是闭包 == 闭包函数有没有自由变量
print(ret.__code__.co_freevars)


# 了解
print(ret.__code__.co_varnames)  # 函数中的局部变量

# 闭包的应用:
# 1,保证数据的安全。
# 2,装饰器的本质。

装饰器

1. 开放封闭原则

? 软件在制作时,不可能把所有功能都设计好,等上线后,后续按需求增加功能,定期迭代更新,对于软件之前写的源代码一般不会修改(函数里面的代码以及函数的调用方式)

开放原则 :在源码不改变的情况下,增加一些额外的功能

封闭原则 :不改变源码

python中的装饰器 :完美的诠释了开放封闭原则

装饰器 :装饰器就是一个函数,它要装饰一个函数,在不改变原函数的源代码以及调用方式的前提下,给其增加一些 额外的功能

2. 初识装饰器

# 1 李业,在一家xx科技有限公司工作,主管安排了一个任务,
# 写一个代码测试怼怼哥写的函数的执行效率。
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园首页')
start_time = time.time()
index()
end_time = time.time()
print(f'此函数的执行效率{end_time-start_time}')
# 2. 主管让你测试小邓,李大象,重复代码太多。
def func1():
    time.sleep(2)
    print('欢迎访问日记首页')

def func2():
    time.sleep(1)
    print('欢迎访问评论首页')
  
start_time = time.time()
func1()
end_time = time.time()
print(f'此函数的执行效率{end_time-start_time}')

start_time = time.time()
func2()
end_time = time.time()
print(f'此函数的执行效率{end_time-start_time}')
# 3.  整合到函数中
def func1():
    time.sleep(2)
    print('欢迎访问日记首页')

def func2():
        time.sleep(1)
        print('欢迎访问评论首页')

def test_time(x):
    start_time = time.time()
    x()
    end_time = time.time()
print(f'此函数的执行效率{end_time-start_time}')

test_time(func1)
test_time(func2)
# 4. 怼怼哥这个函数在实际项目中被500执行,主管要求:在被执行此函数时,
# 同时要测试一下被执行函数的效率。

def index():
    time.sleep(2)
    print('欢迎访问博客园首页')
index()

def test_time(x):
    start_time = time.time()
    x()
    end_time = time.time()
    print(f'此函数的执行效率{end_time-start_time}')
test_time(index)
# 版本4的问题: 开放原则满足了,封闭原则:不改变原函数的源码,以及调用方式。
# 违反了封闭原则:改变了函数的调用方式。
# 版本5: 不能改变原函数的调用方式(闭包):

def index():
        time.sleep(2)
        print('欢迎访问博客园首页')
        index()
        
def func1():
    time.sleep(2)
    print('欢迎访问日记首页')
def test_time(x):  # x = index
        def inner():
        start_time = time.time()
        x()
        end_time = time.time()
        print(f'此函数的执行效率{end_time-start_time}')
        return inner

index = test_time(index)
index()
# 语法糖 @加上装饰器函数的名

def test_time(x):  # x = index
        def inner():
        start_time = time.time()
        x()
        end_time = time.time()
        print(f'此函数的执行效率{end_time-start_time}')
        return inner
  
@test_time  # index = test_time(index)
def index():
        time.sleep(2)
        print('欢迎访问博客园首页')
index()

@test_time
def func1():
        time.sleep(2)
        print('欢迎访问日记首页')
    
@test_time
def func2():
        time.sleep(1)
        print('欢迎访问评论首页')
 

func2 = test_time(func2)
func3 = test_time(func3)

# func2()

'''100行代码'''

# index()


'''10行代码'''

# index()

'''50行代码'''

# index()
# 版本6:被装饰函数有返回值

def test_time(x):  # x = index
        def inner():
        start_time = time.time()
        ret = x()
        end_time = time.time()
        print(f'此函数的执行效率{end_time-start_time}')
        return ret
return inner

@test_time  # index = test_time(index)
def index():
        time.sleep(0.5)
        print('欢迎访问博客园首页')
        return True
print(index())  # inner()

# 你应该是让True返回给index()这样才完美了,但是现在index是inner,所以你要是完全不改变原函数的使用,
# 你print(index()) ---> True
# 版本7: 被装饰函数带参数,无论加不加装饰器,你的实参'太白金星'应该传给形参n,。
# 但版本6不能实现传参,index('太白金星') ==  inner('太白金星')

def test_time(x):  # x = index
    def inner(*args,**kwargs):
        # 函数的定义:* ** 聚合。
        start_time = time.time()
        ret = x(*args,**kwargs)
        # 函数的执行:* ** 打散。
        end_time = time.time()
        print(f'此函数的执行效率{end_time-start_time}')
        return ret
    return inner
@test_time  # index = test_time(index)
def index(n):
    time.sleep(0.5)
    print(f'欢迎{n}访问博客园首页')
    return True

@test_time  # index = test_time(index)
def func2(a,b):
        time.sleep(0.5)
        print(f'最终结果:{a+b}')
        return a + b
print(index('苹果'))  # inner('苹果')
print(func2(1,3)) # == inner(1,3)


def warpper(f):
        def inner(*args,**kwargs):
        '''被装饰函数之前的操作'''
        # print(666)
        ret = f(*args,**kwargs)
        '''被装饰函数之后的操作'''
        # print('执行完毕了')
        return ret
return inner

@warpper
def func():
        print(111)

func()
func()
func()


# 装饰器的应用:在不改变原函数的源码以及调用方式前提下,为其增加额外的功能。
# 登陆认证,打印日志等。

装饰器的标准写法

##装饰器标准写法
def test_(func):
    def inner(*args,**kwargs):
        '执行被装饰函数之前的操作'
        ret = func(*args,**kwargs)
        """执行被装饰函数之后的操作"""
        return ret
    return inner
#登录构架
flag = False
def auth(f):
    def inner(*args,**kwargs):
        if flag:
            '''被装饰函数之前的操作'''
            # 登陆认证:
            # 输入用户名,输入密码
            ret = f(*args,**kwargs)
            '''被装饰函数之后的操作'''
            return ret
        else:
            pass
    return inner


@auth
def article():
    print('欢迎访问文章页面')

@auth
def diary():
    print('欢迎访问日记页面')
    
@auth
def comment():
    print('欢迎访问评论页面')

article()
diary()
comment()

3. 带参数的装饰器

def wrapper(f):
    def inner(*args,**kwargs):
        if f._name_ =='qq':
            ret = f(*args,*kwargs)
            return ret
        else:
            pass
    return inner


def wrapper(f):
    def inner(*args, **kwargs):
        ret = f(*args, **kwargs)
        return ret
    return inner


def wrapper_out(n,*args,sex='男',):
    def wrapper(f):  # f
        def inner(*args,**kwargs):
            ret = f(*args,**kwargs)  # func1()
            return ret
        return inner
    return wrapper

func = wrapper_out(1)  # wrapper函数名
ly = func(func1)  # wrapper(func1) = inner
ly()  # inner()



def wrapper_out(n):
    def wrapper(f):
        def inner(*args,**kwargs):
            # if n == 'qq':
            #     username = input('请输入用户名:').strip()
            #     password = input('请输入密码:').strip()
            #     with open('qq',encoding='utf-8') as f1:
            #         for line in f1:
            #             user,pwd = line.strip().split('|')
            #             if username == user and password == pwd:
            #                 print('登陆成功')
            #                 ret = f(*args,**kwargs)
            #                 return ret
            #         return False
            # elif n == 'tiktok':
            #     username = input('请输入用户名:').strip()
            #     password = input('请输入密码:').strip()
            #     with open('tiktok', encoding='utf-8') as f1:
            #         for line in f1:
            #             user, pwd = line.strip().split('|')
            #             if username == user and password == pwd:
            #                 print('登陆成功')
            #                 ret = f(*args, **kwargs)
            #                 return ret
            #         return False
            username = input('请输入用户名:').strip()
            password = input('请输入密码:').strip()
            with open(n,encoding='utf-8') as f1:
                for line in f1:
                    user,pwd = line.strip().split('|')
                    if username == user and password == pwd:
                        print('登陆成功')
                        ret = f(*args,**kwargs)
                        return ret
                return False
        return inner
    return wrapper



@wrapper_out('qq')
def qq():
    print('成功访问qq')
qq()
# # 看到带参数的装饰器分两步执行:
# @wrapper_out('腾讯')
#     1. 执行wrapper_out('腾讯') 这个函数,把相应的参数'腾讯' 传给 n,并且得到返回值 wrapper函数名。
#     2. 将@与wrapper结合,得到我们之前熟悉的标准版的装饰器按照装饰器的执行流程执行。
@wrapper_out('qq')
def qq():
    print('成功访问qq')

@wrapper_out('tiktok')
def tiktok():
    print('成功访问抖音')

qq()
tiktok()
# 开发思路:增强耦合性

4. 多个装饰器装饰一个函数

针对@ -→ 
装饰函数之前依次从上到下执结果输出, 
执行函数
装饰函数之后依次从后往前结果输出
def wrapper1(func1):  # func1 = f原函数
    def inner1():
        print('wrapper1 ,before func')  # 2
        func1()
        print('wrapper1 ,after func')  # 4
    return inner


def wrapper2(func2):  # func2 == inner1
    def inner2():
        print('wrapper2 ,before func')  # 1
        func2()  # inner1
        print('wrapper2 ,after func')  # 5
    return inner2


@wrapper2  # f = wrapper2(f) 里面的f == inner1  外面的f == inner2
@wrapper1  # f = wrapper1(f) 里面的f == func1  外面的 f == inner1
def f():
    print('in f')  # 3
f()  # inner2()

5. 递归函数

#  初识递归。
def func():
    print('in func')
def func1():
    func()
func1()


#比如:
def func():
    print(666)
    func()
func()


def func(n):
    print(n)
    n += 1
    func(n)
func(1)


# 官网规定:默认递归的最大深度1000次。
# 如果你递归超过100次还没有解决这个问题,那么执意使用递归,效率很低。
import sys
print(sys.setrecursionlimit(1000000))
def func(n):
    print(n)
    n += 1
    func(n)
func(1)


1  太白   18
2  景女神  18 + 2
3  宝元    18 + 2 + 2
4  alex    18 + 2+ 2+2  age(4) = age(3) + 2

def age(n):
    if n == 1:
        return 18
    else:
        return age(n-1) + 2
print(age(4))



def age(4):
    if n == 1:
        return 18
    else:
        return age(3) + 2
age(4) = age(3)  + 2



def age(3):
    if n == 1:
        return 18
    else:
        return age(2) + 2
age(4) = age(2) + 2  + 2



def age(2):
    if n == 1:
        return 18
    else:
        return age(1) + 2
age(4) = age(1) + 2 + 2  + 2    



def age(1):
    if n == 1:
        return 18
    else:
        return age(1) + 2
age(4) = 18 + 2 + 2  + 2    

'''



l1 = [1, 3, 5, ['太白','元宝', 34, [33, 55, [11,33]]], [77, 88],66]
1
3
5
'太白'
'元宝'
34
66

l1 = [1,3,5,['太白','元宝',34],55]
l2 = [1, 3, 5, ['太白','元宝', 34, [33, 55, [11,33]]], [77, 88],66]
for i in l1:
    if type(i) == list:
        for j in i:
            print(j)
    else:
         print(i)



def func(alist):
    for i in alist:
        if type(i) == list:
            func(i)  # func(['太白','元宝',34])
        else:
            print(i)
func(l1)
func(l2)

模块

1. 模块的定义与分类

什么是模块 : 一个py文件就是一个文件

模拟博客园系统作业,100000行代码. 不可能全部存在一个文件.

  1. 不易维护.
  2. 效率低.

分文件: 10个文件.每个文件有50个函数,有一写相同功能或者相似功能的函数.代码冗余,重复性.我们应该将这10个函数提取出来,放在一个文件中,随用随拿.

  1. 节省代码.
  2. 容易维护,组织结构更清晰.

一个模块就是一个py文件,这个模块存储很多相似的功能,相似的函数的集合体.

模块的分类:

  • 内置模块,标准库.python解释器自带的,time,os,sys,等等.200多种.
  • 第三方库(模块),各种大神写的一些模块,通过pip install....安装.6000种.
  • 自己写的模块.自定义模块.

2. import

# import tbjx
# # 当我引用tbjx模块的时候,实际上将tbjx.py执行一遍,加载到内存.
# import tbjx
# import tbjx
# import tbjx
# import tbjx
# import tbjx

# 只是第一次引用时,将此模块加载到内存.
  • 执行文件:02 模块import
  • 被引用文件(模块): tbjx.py

第一次导入模块发生的三件事

import tbjx
n = 1
# 引用模块发生三件事.
'''
    1. 将tbjx.py文件加载到内存.
    2. 在内存中创建一个以tbjx命名的名称空间.
    3. 通过tbjx名称空间的名字.等方式引用此模块的名字(变量,函数名,类名等等).
'''

# print(tbjx.name)
# tbjx.read1()
# tbjx.read2()

3. 被导入模块有独立的名称空间

# 坑:通过tbjx.的方式引用此模块的名字时,一定一定是从此模块中寻找.
# 通过import 引用模块 他有自己的独立名称空间,与当前执行文件没有关系.
name = '李业'
print(tbjx.name)

def read1():
    print('in 02 模块import')

tbjx.read1()

4. 为模块起别名

# 起别名:将一个比较长的模块名化简成简单的.
# import contextlib as cb
# 1 书写方便.
# import tbjx as tb
# print(tb.name)
# tb.read1()
# 2 简化代码.

5. 导入多个模块

# import time,os,sys  # 不推荐.
import time
import os
import sys

# 易于阅读 易于编辑 易于搜索 易于维护。

6. from... import...

# from tbjx import name
# from tbjx import read1
# print(globals())
# 相当于从tbjx模块的全局空间中将name,read1变量与值的对应关系
# 复制到当前执行文件的全局名称空间中.
# print(name)
# read1()

# 优点:使用起来方便了.
# 缺点:容易与当前执行文件产生覆盖效果.

7. from... import...的使用

# 示例1:
# from tbjx import name
# from tbjx import read1
# name = '李业'
# print(name)

# 示例2:
# name = '怼怼哥'
# from tbjx import name
# from tbjx import read1
# def read1():
#     print('在执行文件中')
# # print(name)
# read1()

# 特殊情况:极值情况,工作中不会出现.(了解)
# 因为如果你要是引用一些模块的变量,那么执行文件中就不应该出现同名变量.
# 示例3:
# from tbjx import name
# from tbjx import change
#
# change()
# print(name)

# 示例4:
# from tbjx import change
#
# change()
# from tbjx import name
# print(name)

# 也可以起别名
# from tbjx import name as n
#
# print(n)

一行导入多个

# 导入多个名字
# from tbjx import name
# from tbjx import read1

# from ... import *  尽量别单独用
# from tbjx import *
# print(name)
# read1()
# read2()
# 1,全部将tbjx的所有名字复制过来,无用功.
# 2,容易覆盖.

8. from... import *

from   模块名  import  引用的函数或其他
 
from ...import * 与__all__配合使用(写在模块开头写上:_all_ = ['引用变量名1','引用变量名2'])
 
# from tbjx import *
#
# # read1()
# # read2()
# change()

9. py文件的两种功能

  1. py文件的第一个功能:执行文件(承载代码) 脚本.

    直接打印__name__返回__main__

    调试模块:

    if _name_==‘_main_‘:

    ? 被调试的函数

    这样,被调试的函数只会在本py文件中执行,当被当做模块调用的时候不会执行

  2. py文件的第二个功能: 模块(被执行文件).

    直接打印__name__返回tbjx 模块名

作用:用来控制.py文件在不同的应用场景下执行不同的逻辑(或者是在模块文件中测试代码)

# import tbjx
# import time
# print(time.time())
# # import tbjx
# # tbjx.read1()
# import tbjx1
# tbjx1.read1()

10. 模块的搜索路径

# 寻找模块的路径: 内存 ----> 内置模块  ---> sys.path中找
# 只要这三个地方:内存 内置模块 sys.path可以找到这个引用的模块的路径,这个模块就可以直接引用到.
# import sys
# # print(sys.path)
# # import tbjx
# print(sys.modules)

# 如何引用到tbjx1.py
import sys
# print(sys.path) -- 是一个列表
sys.path.append(r'D:\s23\day15')
# import tbjx
import tbjx1
tbjx1.read1()

序列化模块

序列化模块 :将一个数据结构 ( list,dict… ) 转换成一个特殊的序列( 特殊的字符串 )的过程

# l1 = [1, 2, 3]
# ret = str(l1)
# print(ret,type(ret))
# print(eval(ret))  # 不让用

# 文件存取时,遇到的矛盾.
# dic ={'username': '太白', 'password': 123}

# dic = {1: {'username': '太白', 'password': 123,'status': False},
#        2:{'username': 'alex', 'password': 123,'status': False}

# 这个字典能放在全局么? (不可以,当数据多的时候,加载消耗时间)
# with open('register.json',encoding='utf-8',mode='w') as f1:
#     f1.write(str(dic))
# with open('register',encoding='utf-8') as f1:
#     ret = f1.read()
#     print(ret,type(ret))
#
# # 数据结构 --- > str() 存储在文件, 读取出来时,反转不回去.
# # 网络传输.
# l1 = [i for i in range(100000)]
# # 凡是数据通过网络传出去最终的格式必须bytes
# s1 = str(l1)
# b1 = s1.encode('utf-8')
# print(b1)  # b1可以发送出去
#
# s2 = b1.decode('utf-8')
# print(s2,type(s2))
# s2 转化不成列表了.

# 我们现在要解决的问题: 如果有一种特殊的字符串,这个字符串可以与任何的数据结构互相转换.

1. 序列换模块

# 序列化模块: 将一中数据结构转化成特殊的序列(特殊的字符串,bytes)并且还可以反转回去.

    # json模块: 是所有语言公认的一种序列.最最常用的
    #所以支持的python数据结构有限: int str bool dict list(tuple),None,float

    # None  ---> Null ----> NUll
    # dict  --->
    # pickle模块: 只能python语言中使用的,序列化模块:
    # 支持python所有的数据类型以及对象.
    # shevle模块(不讲): 课下了解(只能是文件存取).

2. json序列化

json序列换化--是所有语言公认的一种序列.最最常用的

两对 四个 方法:

dumps,loads 主要用于网络传输,可以用于文件的读取

import json
# dumps,loads 主要用于网络传输,可以用于文件的存取.
dic = {'username': '太白', 'password': 123,'status': False}
ret = json.dumps(dic) # 转换成特殊的字符串供网络传输
print(ret,type(ret))
\\{"username": "\u592a\u767d", "password": 123, "status": false} 

ret_dict = json.load # 转换成源数据类型
print(ret_dict)
\\{'username': '太白', 'password': 123, 'status': False}

# 特殊的参数
dic = {'username': '太白', 'password': 123,'status': False}
ret = json.dumps(dic,ensure_ascii=False,sort_keys=True) #ensuir_ascii 解决中文 sork_key 排序
print(ret,type(ret))
\\{"password": 123, "status": false, "username": "太白"} 

# 文件的读取
import json
dic = {'username': '太白', 'password': 123,'status': False}
s_dict = json.dumps(dic)
with open('jsonlx.json',encoding='utf-8',mode='w') as f1:
     f1.write(s_dict)

with open('jsonlx.json',encoding='utf-8') as f


评论


亲,登录后才可以留言!