最全python基础整理(二)

一、函数

函数是实现特定功能的代码段的封装,在需要时可以多次调用函数来实现该功能

1. 内置函数

Python内置了许多非常有用的函数,可以直接调用

2. 自定义函数
语法:

def 函数名(形参1,形参2,...):
	 函数体

注意:

  • 函数名可以包含数字、字母、下划线,但不能以数字开头
  • 如果函数有返回值,使用return关键字
  • 定义函数后函数中的代码并不会执行,需要调用函数才会执行
# 定义函数,使用def
def calc(num1, num2):  # 必选参数,也称为位置参数,不能省略
    res = num1 + num2
    return res


# print(calc(3, 5)) # 调用函数
# 参数类型检查
def my_abs(x):
    # 可以为函数添加文档注释,也称为文档字符串doc string
    """ 计算绝对值 :param x: 参数 :return: 返回x的绝对值 """
    # 对参数类型进行检查
    if not isinstance(x, (int, float)):
        raise TypeError('参数类型不正确,只能为数值类型')
        # 抛出异常
    if x >= 0:
        return x
    else:
        return ­x
    # print(my_abs('aaa'))
    # print(help(my_abs))
    # 默认参数,即有默认值的参数


def my_pow(x, y=2):
    if y == 0:
        return 1
        res = x
        for i in range(y - 1):
            res *= x
            return res
    # print(my_pow(5))


# 可变参数,使用*号,表示参数个数是可变的
def my_sum(x, *y):
    print(x)
    print(y)  # 接收到的实际上是一个tuple


# my_sum(3, 5, 8, 12, 4)
# 不建议下面的这种写法,建议将必选参数放在最前面
def my_sum2(*y, x):
    print(y)
    print(x)


my_sum2(12, 4, 2, 7, x=9)  # 必选参数在后面时需要指定参数名
# 对于可变参数,可以直接传入list或tuple,只需要在参数前添加一个*
nums = [12, 4, 2, 64, 23, 9]


# my_sum(4, nums[0], nums[1], nums[2], nums[3], nums[4], nums[5])
# my_sum(4, *nums) # 关键字参数,使用**,也表示参数个数是可变的,但传递的是带名称的参数
def f1(x, **y):
    print(x)
    print(y)  # 接收到的实际上一个dict


# f1(3, a=5, b=9, c=18)
# 对于关键字参数,可以直接传入一个dict,只需要在参数前添加**
user = {'id': 1001, 'name': 'tom', 'age': 18}


# f1(4, id=user['id'], name=user['name'], age=user['age'])
# f1(4, **user)

# 命名关键字参数,限制关键字参数的名字,使用*分隔,*号后面的参数表示命名关键字参数

def f2(x, *, name, age):
    print(x)
    print(name)
    print(age)


# f2(4, name='alice', age=20)

# 接收任意参数
def f3(*args, **kwargs):
    print(args)
    print(kwargs)


f3(1, 43, 'aaa', name='alice', age=20)


# 空函数,表示以后再实现
def empty():
    pass  # 使用pass


# 函数的返回值,返回多个值
def f1():
    name = 'tom'
    age = 20
    sex = 'male'
    return name, age, sex


# print(f1()) # 返回值实际上是一个tuple

a, b, c = f1()


# print(a, b, c)

# 函数的返回值,返回一个函数,即将函数作为返回值

def f2(x):
    print(111)
    z = 6


def f3(y):
    print(x * y+z)  # 内部函数使用了外部函数的参数或局部变量,称为闭包
    return f3


# fn = f2(3)
# fn(5)


# 递归函数:一个函数在内部调用自身,这个函数就是递归函数
# 计算x的y次方,如计算25次方
def calc(x, y):
    # 常规方式
    # if y == 0:
    # return 1
    # i = 1
    # res = x
    # while i < y:
    # res *= x
    # i += 1
    # return res

# 递归方式
# 2*2*2*2*2=2*(2*2*2*2)=2*(2*(2*2*2))=
    if y == 0:
        return 1
    else:
        return x * calc(x, y-1) # 不停的调用自己,递归太深可能会抛出栈溢出异常
print(calc(2, 99999999999999))

3. 变量作用域和命名空间

''' 
变量作用域scope:指的是变量生效的区域 
    两种作用域: 
        1.全局作用域 
            函数以外的区域都是全局作用域 
            在全局作用域中定义的变量,都是全局变量 
        2.函数作用域,也称为局部作用域 
            函数内的区域,每调用一次函数就会创建一个新的函数作用域 
            在函数作用域中定义的变量,都是局部变量 
            
        变量的查找顺序: 
            先在当前作用域中查找,如果没有则向上一级作用域中查找,直到查找全局作用域,如果还是没有,则报错 
'''

a = 5 # 全局变量
if True:
    c = 5 # 全局变量,在Python中没有块级作用域

def fn():
    b = 8 # 局部变量
    print('函数内部:a=', a)
    print('函数内部:b=', b)
    print('函数内部:c=', c)

fn()
print('函数外部:a=', a)
# print('函数外部:b=', b)
print('函数外部:c=', c)

x = 1

def f1():
    x = 2

def f2():
    x = 3
    print(x)


print('­' * 80)



# global关键字
def fn2():
    # a = 10 # 在函数中为变量赋值时,默认都是为局部变量赋值
    # 如果希望在函数中修改全局变量,要使用global关键字来声明变量
    global a
    a = 10

    print('函数内部:a=', a)

fn2()
print('函数外部:a=', a)
print('*' * 80)

''' 
    命名空间namespace:指的是变量存储的位置,每一个变量都要存储在指定的命名空间中 
    每个作用域都有一个对应的命名空间 
    全局命名空间,用来存储全局变量;函数命名空间,用来存储函数中的变量 
    命名空间实际上就是一个字典dict,是一个专门用来存储变量的字典 
    '''

# locals() 获取当前作用域的命名空间
scope = locals() # 在全局作用域中调用locals(),获取的就是全局命名空间
print(scope)
print(type(scope))


# 通过scope操作命名空间中的变量(不建议)
print(scope['a'])
scope['c'] = 666
scope['z'] = 'tom'
print(scope['c'])
print(scope['z'])
# print(z)
print('*' * 80)


def fn3():
    a = 888
    scope = locals() # 在函数中调用locals(),获取到的是函数命名空间
    scope['b'] = 222
    print(scope)
    print(scope['b'])
    # globals() 可以在任意位置获取全局命名空间
    global_scope = globals()

    print(global_scope)
    print(global_scope['a'])

fn3()

4. 高级特性
迭代和列表生成式

# 导入模块
import collections
''' 
迭代:也称为遍历,循环获取每一个元素 
'''
for i in ['tom', 'jack', 'alice']:
    print(i, end=' ')
print()

for i in ('tom', 'jack', 'alice'):
    print(i, end=' ')
    print()

for i in {'name': 'tom', 'age': 18, 'sex': 'male'}.keys():
    print(i, end=' ')
print()

for k, v in {'name': 'tom', 'age': 18, 'sex': 'male'}.items():
    print(k, v)

for i in 'hello':
    print(i)

# 判断对象是否是可迭代的
print(isinstance('hello', collections.Iterable))


# 获取索引和值
# 方式1:自己获取索引
names = ['tom', 'jack', 'alice']
for i in range(len(names)):
    print(i, names[i])

# 方式2:使用enumerate()函数,转换为索引­元素对
print(enumerate(names))
print(isinstance(enumerate(names), collections.Iterable))

for k, v in enumerate(names):
    print(k, v)

print('­' * 80)
''' 
列表生成式:用来创建list的生成式 
'''
# 生成[0,99]的list
# nums = range(0, 100)



nums = list(range(0, 100)) # 转换为list
# print(nums, type(nums))

# print(isinstance(range(0, 100), collections.Iterable))

# for i in range(0, 100):
#     print(i)

# 生成一个包含[1,100]之间所有3的倍数的list

# 方式1

# lst = []
# for i in range(1, 101):
#   if i % 3 == 0:
#       lst.append(i)

#方式2
lst = [i for i in range(1, 101) if i % 3 == 0] # 等价于a = list(range(1, 101))
print(lst)

迭代器和生成器

''' 
迭代器iterator:用来访问集合元素的一种方式,可以记住迭代的位置 
'''
nums = [3, 8, 12, 54, 2, 7]
it = iter(nums) # 调用iter()函数创建迭代器
print(type(it))

print(next(it)) # 调用next()函数获取迭代器的下一个元素
print(next(it)) # 只能往前不能后退

# 使用for...in循环遍历迭代器
for i in it:
    print(i)

''' 
    生成器generator:在循环过程中依次计算获取值的对象(节省空间、效率高) 
    创建生成器的方式: 
        方式1:把一个列表生成式的[]改成() 
        方式2:在函数中使用yield关键字,此时该函数就变成一个生成器函数 
'''
# 方式1:把一个列表生成式的[]改成()
generator = (i for i in range(1, 100))
print(type(generator)) # generator类型

# 获取生成器的下一个值
print(next(generator)) # 获取时才生成值,类似于Oracle中sequence
print(next(generator))
print(next(generator))

# 使用for...in循环遍历生成器
for i in generator:
    print(i)
print('­' * 80)


# 方式2:在函数中使用yield关键字,此时该函数就变成一个生成器函数
def gen():
    print('one')
    yield 13
    print('two')
    yield 8
    print('three')
    yield 25
    print('four')
    yield 38

# 生成器函数与普通函数的执行流程不一样:
# 普通函数是顺序执行,执行到最后一行或遇到return时结束
# 生成器函数是在每次调用next()时执行,遇到yield语句就返回,下一次调用next()时会从上次返回的yield语 句处继续执行
g = gen() # generator类型
print(type(g))
print(next(g))
print(next(g))

# 使用for...in循环遍历生成器
for i in g:
    print(i)

高阶函数

''' 
高阶函数:一个函数接收另一个函数作为参数,这种函数称为高阶函数 
'''
nums = [12, ­4, 3, ­23, 65, 1, ­234, 22]

# 定义一个函数,用来检查数字是否大于5
def f1(x):
    if x > 5:
        return True
    return False

# 自定义高阶函数,用来过滤列表中的元素

def fn(fun, lst):
    """ 将列表中所有符合条件的元素筛选出来,返回一个新列表
        :param fun: 条件函数
        :param lst: 要进行筛选的列表
        :return: 返回新列表
"""
new_list = []
for i in lst:
    if fun(i):
        new_list.append(i)
return new_list

nums1 = fn(f1, nums)
print(nums1)


def f2(x):
    return x % 2 == 0

print(fn(f2, nums))

# 内置高阶函数 filter(),用于过滤序列
nums2 = filter(f1, nums)
print(list(nums2))

# 内置高阶函数 map(),用于处理序列
def f3(x):
    return x * x

nums3 = map(f3, nums)
print(list(nums3))

# 内置高阶函数 sorted(),用于排序 
print(sorted(nums)) 
print(sorted(nums,key=abs))

匿名函数和装饰器

''' 
匿名函数:没有名字的函数,使用lambda关键字 
'''

nums = [12, 4, 32, 5, 23, 7]

# def fn(x):
#   return x * 2 + 1

nums_new = list(map(lambda x: x * 2 + 1, nums))
print(nums_new)



# 将匿名函数赋给变量(不建议)
a = lambda x: x + 1
print(a(2))
print('­' * 80)

''' 
装饰器:在代码运行期间动态增加功能,称为装饰器Decoration,类似于AOP 
'''

# 定义一个装饰器,为函数添加打印日志的功能

def log(fn):
    def wrapper(*args, **kwargs):
        print('开始执行%s()函数。。。' % fn.__name__)
        res = fn(*args, **kwargs)
        print('执行%s()函数结束。。。' % fn.__name__)
        return res
    return wrapper # 返回装饰函数


# @log
def even(lst):
    for
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初夏0811

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值