表达式,推导式,名称空间与作用域,函数的嵌套定义

一,复习

# 字符串的比较
#     -- 按照从左往右比较每一个字符,通过字符对应的ascll进行比较
# print('a' > 'A')    #True
# print('ac' > 'ab')  #True

# 函数的参数
# 1)实参与形参:
#    -- 形参:在函数定义时()中出现的参数 
#    -- 实参:在函数调用时()中出现的参数

# 2)实参的分类
#    -- 位置实参:给位置形参,必须按位置
#    -- 关键字实参:给位置与关键字形参,不需要按顺序

# 3)形参的分类
#    -- 无值位置
#    -- 有值位置
#     -- 可变长位置
#    -- 有无值关键字
#    -- 可变长关键字
def fn(a, b=10, *args, x, y=20, z, **kwargs): pass

# 4)打散机制
def func(*args, **kwargs):
    pass
func('a', 'b', 'c', a=1, b=2)
func(*'abc', **{'a': 1, 'b': 2})  # args=('a', 'b', 'c')  kwargs={'a': 1, 'b': 2}


# 函数的嵌套调用
#     -- 在被调用的函数中调用其他函数:在被调用的函数中要去使用其他函数的功能

二,今日内容

# 1.函数默认值的细节:理解一下 *
# 2.数据类型的补充:语法简单,经常去使用就ok ***
#    -- 三元表达式 | 列表推导式 | 字典推导式

# 3.函数对象:函数名的各种应用场景 *****
# 4.名称空间与作用域:解释变量名重复与冲突问题 *****
# 5.函数的嵌套定义:在函数内部定义函数 *****

三,函数默认值的细节

# 如果函数的默认参数的默认值为变量,在所属函数定义阶段一执行就被确定为当时变量存放的值
a = 100
def fn(num=a):
    print(num)  # 100
a = 200
fn()

四,三元表达式:就是if...else...的语法糖

# 三目运算符:用于简化 if...else...的语法结构
#       -- 1) 只能解决if...else...结构,其他if分支结构都不管
#       -- 2)一个分支提供一个结果: 如果一个分支提供了多个结果, 将多个结果通过元组返回

a = int(input('a: '))
b = int(input('b: '))
res = a if a > b else b
print(res)

五,列表与字典推导式

# 1,快速生成列表或字典的语法糖,且能在生成过程中添加简单的逻辑

# 能被列表推导式推导的数据源必须在循环取值时可以得到一个值
ls = [v for v in range(1, 6)]
print(ls)  # [1, 2, 3, 4, 5]

ls = ['奇数' if v % 2 != 0 else '偶数' for v in range(1, 6)]
print(ls)  # ['奇数', '偶数', '奇数', '偶数', '奇数']

# 应用:
# 1)多数据场景
print([v for v in range(1, 31)])
# 2)推导式可以拥有简单的逻辑

# 能被字典推导式推导的数据源必须在循环取值时可以被解压赋值为两个值
ls = [['A', 1], ('B', 2)]
res = {k.lower(): v for k, v in ls}
print(res)
res = {v: k.lower() for k, v in ls}
print(res)

六,函数对象

# 在python中,所有变量存放的值只要是地址,我们就称之为对象
#    -- 所有的变量都是用来存放地址的,所以都是对象
#    -- 存放整型的地址就是整型对象 | 存放函数的地址就是函数对象 | 存放文件的地址就是文件对象

# 函数对象:存放函数地址的变量就是函数对象
  def fn(): pass   my_fn = fn
# my_fn | fn都存着函数地址,所以都是函数对象,函数对象的使用就是 函数对象() 来调用函数 # 函数对象的应用场景***
# 1.函数对象()就是调用函数 # 2.函数对象可以直接作为变量赋值给其他变量 # 3.函数对象可以作为函数的参数 # 4.函数对象可以作为函数的返回值 # 5.函数对象可以作为容器类型的成员 # 1.函数对象()就是调用函数 def fn1(): pass fn1() # 2.函数对象可以直接作为变量赋值给其他变量 def fn2(): pass my_fn = fn2 print('>>>', my_fn, fn2) my_fn() # 3.函数对象可以作为函数的参数 def fn3(func): # func = my_fn = fn2 func() fn3(my_fn) # 4.函数对象可以作为函数的返回值 def fn4(): return my_fn my_fn2 = fn4() # 5.函数对象可以作为容器类型的成员 ls = [my_fn, my_fn2]

七,函数对象案例

# =============================part1===========================
'''
# 加法运算
def add(n1, n2):
    return n1 + n2

def low(n1, n2):
    return n1 - n2

# 四则运算
def computed(n1, n2, func):
    # if cmd == 'add':
    #     return add(n1, n2)
    # elif cmd == 'low':
    #     return n1 - n2
    return func(n1, n2)

r1 = computed(10, 20, add)
print(r1)
r2 = computed(10, 20, low)
print(r2)
'''

#=============================part2===========================
"""
def add(n1, n2):
    return n1 + n2

def low(n1, n2):
    return n1 - n2

def computed(n1, n2, func):
    return func(n1, n2)

cmd = input('cmd: ')  # 只能等于字符串add、low => 什么方式可以将字符串add、low对应上函数
# fn = None
# if cmd == 'add':
#     fn = add
# elif cmd == 'low':
#     fn = low
# computed(10, 20, fn)

fn_map = {
    'add': add,
    'low': low
}

if cmd in fn_map:  # 作为容器的成员可以简化判断逻辑
    fn = fn_map[cmd]
    res = computed(10, 20, fn)
    print(res)
else:
    print('该运算暂不支持')
"""

#=============================part3===========================
"""

def add(n1, n2):
    return n1 + n2

def low(n1, n2):
    return n1 - n2

def jump(n1, n2):
    return n1 * n2

def computed(n1, n2, func):
    return func(n1, n2)
    
fn_map = {
    'add': add,
    'low': low,
    'jump': jump
}

def get_fn(cmd):
    f = add  # 默认为add函数
    if cmd in fn_map:
        f = fn_map[cmd]  # 如果指令正确就返回对应的函数,如果不正确,就是采用默认的函数
    return f

while True:
    cmd = input('cmd: ')
    if cmd == 'q':
        break

    fn = get_fn(cmd)
    res = computed(10, 20, fn)
    print(res)


# while True:
#     cmd = input('cmd: ')
#     if cmd == 'q':
#         break
#     if cmd in fn_map:
#         fn = fn_map[cmd]  # 通过指令找函数
#         res = computed(10, 20, fn)
#         print(res)
#     else:
#         print('该运算暂不支持')
"""


# =============================part4===========================

# 功能层
def add(n1, n2):
    return n1 + n2
def low(n1, n2):
    return n1 - n2

def jump(n1, n2):
    return n1 * n2

# 实现层
def computed(n1, n2, func):
    return func(n1, n2)

# 映射层
fn_map = {
    'add': add,
    'low': low,
    'jump': jump
}

# 完成映射对应
def get_fn(cmd):
    f = add  # 默认为add函数
    if cmd in fn_map:
        f = fn_map[cmd]  # 如果指令正确就返回对应的函数,如果不正确,就是采用默认的函数
    return f

# 程序入口
while True:
    cmd = input('cmd: ')
    if cmd == 'q':
        break

    fn = get_fn(cmd)
    res = computed(10, 20, fn)
    print(res)

八 ,名称空间

# 名称空间:就是名字与地址的对应关系,可以被Python解释器遍历查找,采用堆栈存储方式
# LEGB

# 三种名称空间
# Built-in:内置名称空间;系统级,一个;随解释器执行而产生,解释器停止而销毁
# Global:全局名称空间;文件级,多个;随所属文件加载而产生,文件运行完毕而销毁
# Local:局部名称空间;函数级,多个;随所属函数执行而产生,函数执行完毕而销毁

# 注:文件中的if、while、for、with这些能产生缩减的关键字并不能产生名称空间
# 加载顺序:Built-in > Global > Local

九,函数嵌套定义

# 概念:在一个函数内部定义另一个函数
def outer():
    print('outer run')
    a = 10
    # 函数对象(变量)与普通对象(变量)一样,在函数内部定义,随函数调用而产生,
    # 调用结束而销毁,所以只能在函数内部调用
    def inner():
        print('inner run')
    inner()
outer()

十,作用域

# 作用域:变量(名字|对象)起作用的范围
# 四种作用域, LEGB # Built-in:内置作用域:作用所有文件的所有地方 # Global:全局作用域:作用当前文件的所有地方 # Enclosing:嵌套作用域:作用当前函数与内部被嵌套函数 # Local:局部作用域:作用当前函数内部 # 注: # 不同作用域之间名字不冲突,以达到名字的重用 # 每个作用域优先使用自己作用域中的名字,没有再找更大的名称空间的名字,直到内置,还没有就报错 # 查找顺序:Local > Enclosing > Global > Built-in
原文地址:https://www.cnblogs.com/HZLS/p/10784051.html