Python基础 2

一、函数

1、参数

def func(形参, *args, 关键字参, **kwargs)
pass

2、作用域

global:声明一个变量是全局变量。

nonlocal:声明一个变量是局部变量,用在函数嵌套中,内层函数用来声明一个变量是局部中离它最近的同名局部变量。如果声明的这个变量在局部中没有则报错,或者声明的这个变量在局部已经被声明为全局变量也报错。

3、命名空间

命名空间就是变量名和值的对应关系,分为内置、全局和局部,变量会分别保存在这三个地方。

函数里的变量只有在函数被执行时才会开辟命名空间,当函数执行完毕后又被清除,外部无法调用。

4、闭包

定义:在内层函数使用外层函数的变量

作用:1、保护变量不被全局中其他的函数改变。如果直接一层函数,并且使用全局变量,那这个变量很可能被其他函数修改,导致需要的变量值不对。2、常驻内存,使得局部的变量不被清除,为装饰器做铺垫。

def func1():
    a = 111
    def func2():
        return a
    return func2

func = func1()
f = func()
print(f)
举个例子

5、匿名函数

匿名函数一般搭配内置函数一起使用。

lambda x:x+1 

6、内置函数

(1) sorted

sorted用来给可迭代对象排序,有三个参数:iterable可迭代对象、key排序规则、reverse是否倒序。

sorted是创建列表将排序好的数据都放到新的列表,原数据并不改变,而列表的.sort()方法是修改原列表。

sorted不管传入的是什么数据类型,返回的都是列表,如果传入的是一个字符串,会将每个字符排序放入列表,如果传入的是一个字典,会将字典的键排序。

l = ["aaaaa", "aaa", "a", "aaas"]
print(sorted(l, key=lambda x:x.count("a"), reverse=False))  # 将列表按照含a的个数从小到大排序

d = [{"name": "小黑", "age": 3}, {"name": "小红", "age": 2}, {"name": "小明", "age": 1}]
print(sorted(d, key=lambda x:x["age"]))

(2) filter

filter用来对可迭代对象做过滤,有两个参数:function 规则、iterable 可迭代对象。

按照规则如果返回真则保留,返回假就不要。最后返回的是一个迭代器,需要用list()转换成列表。

l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(lambda x: x % 2 == 0, l)))  # 得到一个只有偶数的列表

(3) map

map对每个数据做一些操作,需要两个参数:func 规则、iterable可迭代对象。

l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(map(lambda x: x + 1, l)))  #得到一个每个数都加1的列表

(4) zip

zip把传入的一个或多个可迭代对象中,索引值相同的元素打包成一个元祖,最后返回一个迭代器。

l1 = [1, 2, 3]
l2 = [3, 2, 1]
print(list(zip(l1, l2)))
>>>[(1, 3), (2, 2), (3, 1)]

(5) isinstance 和 issubclass

isinstance(obj, cls) 判断对象是否属于某个类型,包含继承关系。

issubclass(son, father) 判断一个类是否是一个类的子类。

 

二、装饰器

装饰器就是在不改变函数代码的前提下给函数添加新的功能。

1、装饰器的基本格式

def wrapper(func):
    def inner(*args,**kwargs):
        print("111")
        ret = func(*args,**kwargs)
        print("222")
        return ret
    return inner

@wrapper
def test():
    a = 1
    return a

2、装饰器的wraps

实际上@wrapper就是执行了test = wrapper(test),使得我们调用的test函数变成了wrapper函数,导致函数的信息也变成了wrapper的,比如函数的名字,给装饰器内层的函数添加一个@wraper可以让函数的信息维持原来的样子。

from functools import wraper

def wrapper(func):
    @wraper
    def inner(*args,**kwargs):
        print("111")
        ret = func(*args,**kwargs)
        print("222")
        return ret
    return inner

@wrapper
def test():
    a = 1
    return a

3、带参数的装饰器

def outer(a):
    def wrapper(func):
        def inner(*args,**kwargs):
            xxxxx
            return 
        return inner
    return wrapper

@outer(xx)

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

@wrapper1

@wrapper2

def xxxxx

这样会先执行1里func前的代码,再执行2中func前的代码,再执行func,再执行2中func后的代码,在执行1func后的代码。

三、迭代器

迭代器可以让不同的数据类型有相同的遍历方式。

只要含有__iter__方法的都是可迭代对象——可迭代协议

只要含有__next__和__iter__方法就是迭代器——迭代器协议

迭代器定义:实现了无参数的__next__方法,返回序列的下一个元素,如果没有元素了则抛出StopIteration异常,且实现了__iter__方法,返回迭代器本身,所以迭代器也可以迭代。

当使用for循环遍历一个列表(可迭代对象时)时,会执行列表的__iter__方法,将列表转换成一个迭代器,之后通过迭代器的__next__方法依次取值。

注意:可迭代对象一定不能是迭代器,因为迭代器只能遍历一次,如果可迭代对象本身也是一个迭代器(实现了__next__方法),那么遍历一次后就没用了,所以必须在每次需要遍历时生成一个新的迭代器去遍历。

四、生成器

定义:只要有yield关键字的函数,就是生成器函数。

生成器本质是迭代器,是迭代器的一种。

生成器函数在调用时不执行内部语句,只有在.__next__方法时,才执行到第一个yield为止,在下一次执行__next__方法时,执行到第二个yield。

注意,生成器里的值只能取一次。

特点:1、省内存,存的是代码,不是数据。2、惰性机制。3、只能向前,不能反复。

def func():
    yield 1
    yield 2
    yield 3
    yield 4

>>> temp = func()
>>> temp.__next__()
1
>>> temp.__next__()
2
>>> temp.__next__()
3
>>> temp.__next__()
4
>>> temp.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
生成器示例

一、创建生成器的两种方式:

def func():
    print(111)
    yield "111"

print(func().__next__)
1、生成器函数
g = (i for i in range(10))
2、生成器表达式

二、next和send

# 生成器可以通过__next__方法取值
def func():
    yield 1
    yield 2
    yield 3

g = func()
print(g.__next__())
print(g.__next__())
print(g.__next__())
next
# 生成器还可以通过send取值,并且send可以给上一个yield赋值
# 因为send是给上一个yield赋值,所以第一次只能用__next__
def func():
    print("开始")
    a = yiled "1"
    print("a:",a)
    b = yiled "2"
    print("b:",b)
    c = yiled "3"
    print("c:",c)
    yiled "结束"

g = func()
print(g.__next__())  # 开始  1
pritn(g.send("这是a"))  # a:这是a  2
pritn(g.send("这是b"))  # b:这是b  3
pritn(g.send("这是c"))  # c:这是c  结束
send

三、惰性机制

生成器的惰性机制让生成器只有在取值的时候才会执行,否则生成器中保存的只是代码,没有数据。

def add(a,b):
    return a + b

def gen():
    for i in range(4):
        yield i

g = gen()

for n in [2, 10]:
    g = add(n,i) for i in g    # 这里生成器g并没有取值,所以并不执行这段代码,只是把这段代码完整的代入下一次循环,n没有机会等于2,只会等于10

print(list(g))    
# 这里g被取值了,实际上现在等于执行的是 [add(n, i) for i in (add(n,i) for i in g)],这时的n都是10

四、各种推导式

[i for i in range(10)]  # 列表推导式
{i:i+1 for i in range(10)}  # 字典推导式
{i for i in range(10)}  # 集合推导式
a if a > b else b # 三元运算符

用生成器自定义一个range函数:

def nrange(num):
    n = 0
    while n < num:
        yield n
        n += 1
    return

for i in nrange(10):
    print(i)

#得到 0,1,2,3,4,5,6,7,8,9
View Code

 

五、其他基础知识

1、globals()函数

globals函数可以返回一个字典,字典的键是当前模块中所有的全局变量、函数、类的名字,值就是相应的对象,可以使用globals()函数寻找当前模块中名字符合某些条件的类、函数或变量

[globals()[key] for key in globals() if key == 'xxxx']

2、策略模式

策略模式是在有很多种选择的处理方法时,通过一个通用接口来调度不同的“策略”,如购物结算时的折扣方式,可以将不同的优惠策略封装成不同的方法,用一个统一的入口取调用这些方法。

posted @ 2019-05-11 00:30  不可思议的猪  阅读(211)  评论(0编辑  收藏  举报