python函数参数生成器_Python函数、生成器、异常处理

函数:命名空间、多个值返回、函数作为对象、Lambda;

生成器:生成器表达式、itertools;

错误与异常捕获:try 语句的使用;

参数

函数是实现代码复用与组织化最重要的方法,函数用 def 关键字定义:

1

2

3

4

5def my_func(x,y,z=1.5):

if z>1:

return z*(x+y)

else:

return z/(x+y)

python中返回多个值也是没问题的,如果你写的函数没有返回值,那么默认python会返回 None.

每个函数都有 positional arguments 和 keyword arguments. keyword arguments 在设置函数的默认参数的时候用的比较多,在前面的函数中,x和y是 positional arguments,而z是 keyword arguments。

这些参数的顺序是有限制的:

keyword arguments must follow the positional arguments(if any).

命名空间

函数可以访问两种类型的变量,global 和 local 的,中文叫全局的或局部的。

局部变量在函数运行的时候马上创建,如果函数运行完毕,马上会被销毁(也有例外,但不在这里的讨论范围之内)。

比如下面的函数:

1

2

3

4def func():

a = []

for i in range(5):

a.append(i)

func()函数调用后,在它的内部创建了一个空的数组,然后5个元素添加了进去,但当函数运行结束后,a马上就会被销毁。

假设将代码改成这样:

1

2

3

4a = []

def func():

for i in range(5):

a.append(i)

修改函数外面的变量是可能的,但这些变量必须声明为 global 类型:

1

2

3

4

5a = None

def bind_a_variable():

global a

a = []

bind_a_variable() # 输出 []

个人不是很推荐使用 global 关键字,通常来说全局变量都用来存储一些系统的状态,如果你需要大量的使用,更推荐你用更面向对象的方式,例如类。

返回多个值1

2

3

4

5def f():

a = 5

b = 6

c = 7

return a,b,c

python的函数可以返回多个值,它们会被包装成一个元组,随后再被解包。

函数作为对象

因为python的函数也是对象,所以可以做很多别的语言很难做到的事情。

假设我们有一些数据需要清理:

1states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda','south carolina##', 'West virginia?']

如果你处理过用户提交上来的数据就懂我说的,很多简直想象不到输入都会发生,对于那些输入,我们要去掉首尾空格,多余的符号,正确的首字母大小写等等。一种方法是,我们可以用自带的re正则模块:

1

2

3

4

5

6

7

8

9import re

def clean_strings(strings):

result = []

for value in strings:

value = value.strip()

value = re.sub('[!#?]','',value)

value = value.title()

result = append(value)

上面的结果看起来是这样的:

1

2

3clean_strings(states)

输出:

['Alabama','Georgia', 'Georgia', 'Georgia', 'Florida', 'South Carolina', 'West Virginia']

我们函数作为对象,存到数组中,来实现这一需求:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18def remove_punctuation(value):

return re.sub('[!#?]', '', value)

# 函数数组

clean_ops = [str.strip,remove_punctuation,str.title]

# ops参数接受函数数组对象

def clean_string(strings,ops):

result = []

for value in strings:

for function in ops:

value = function(value)

result.append(value)

return result

clean_string(states,clean_ops)

输出是一样的:

['Alabama','Georgia', 'Georgia', 'Georgia', 'Florida', 'South Carolina', 'West Virginia']

这种方式可以让你的代码更解耦。

用map方法也可以将一个函数作用到序列的每一个元素上:

1

2for x in map(remove_punctuation,states):

print(x)

Lambda

Lambda是把那些很简短的函数形式做了简化,让你可以用一种非常简单的方式定义一个函数,然后将这个小函数用在需要它的地方,这在特定的情境下,非常方便:

1

2

3

4def short_function(x):

return x* 2

# 等于

equiv_anon = lambda x: x*2

看下面代码:

1

2

3

4

5def apply_to_list(some_list,f):

return [f(x) for x in some_list]

ints = [1,2,3,4]

apply_to_list(ints,lambdax:x*2)

你可以在参数中,直接定义要传进去的参数。

再来看另一个例子,你有一堆字符,你需要根据每一个字符中字母出现的个数多少来排序(重复的不算):

1

2strings = ['foo', 'card', 'bar', 'aaaa', 'abab']

strings.sort(key= lambda x: len(set(list(x))))

list,会将字母串分解

set,会去掉重复的字母

最后算出每个字母串的长度并以此排序。

lambda函数是没有name属性的

生成器

可以将iter函数作用到序列上,这样便返回了一个生成器。

1

2

3

4dict_iterator = iter(some_dict)

dict_iterator

输出:

可以用list包含一个生成器,得到内部的值:

1list(dict_iterator)

生成器是惰性的,比如你要读一个文件有一万行,你不需要一次性全部的读取,用生成器,你只需要一行一行的返回。

生成器表达式

生成器表达式和列表推导式有些类似,不过包裹它的是括号:

1

2

3gen = (x ** 2 for x in range(100))

gen

# 输出 at 0x109cbf3b8>

上面这种写法和下面的代码完全一样:

1

2

3

4def make_gen():

for x in range(100):

yield x**2

gen = make_gen()

生成器可以像数组一样当作函数的参数,比如计算list內所有数的和:

1

2

3

4

5gen = [x ** 2 for x in range(100)]

sum(gen) # 输出328350

gen = (x ** 2 for x in range(100))

sum(gen) # 生成器当作参数,一样输出328350

itertools

itertools标准库为一些常用的数据,内置了一些通用的生成器。

1

2

3

4

5

6

7

8

9

10

11

12

13

14import itertools

first_letter = lambda x: x[0]

names = ['Alan', 'Adam', 'Wes', 'Will', 'Albert', 'Steven']

for letter, names in itertools.groupby(names, first_letter):

print(letter, list(names)) # names is a generator

# 输出

A ['Alan', 'Adam']

W ['Wes', 'Will']

A ['Albert']

S ['Steven']

错误与异常捕获

健壮的程序一定要有错误与异常捕获,我么要进行类型转化:

1

2float('1.2345') ---> 1.2345

float('string') ---> value error

我们定义一个函数来捕获这个异常:

1

2

3

4

5def attemp_float(x)

tyr:

return float(x)

except:

return x

这时候,如果捕获到了value error,就会返回输出的数据:

1

2float('1.2345') ---> 1.2345

float('string') ---> string

函数有可能会返回别的错误,这时候需要把可能出现的错误写出来:

1

2

3...

except(TypeError,ValueError)

...

在文件读取中,你打开了一个文件,不管你有没有操作,你都需要把它关闭,这时候就需要用到final语句,即不管前面是否捕获到了异常,最终都要做的事情:

1

2

3

4

5f = open(path,'w')

try:

write_to_file(f)

finally:

f.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值