Python学习笔记第三天

函数

函数的概念

内置函数 python语言提供类的方法的快捷方式

来自luotianshuai同学的整理:

面向过程:根据业务逻辑从上到下写垒代码

函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

函数作用是你的程序有良好的扩展性、复用性。

同样的功能要是用3次以上的话就建议使用函数。


标注:不能死记,

函数可以理解为一个一个的功能块,你把一个大的功能拆分成一块一块的,用某项功能的时候就去调用某个功能块即可!

函数可以理解为:乐高积木,给你一块一块的,你可以用这些积木块组成你想要的任何,功能!

函数可以调用函数!主函数的作用就是把函数进行串联、调用!函数本身是不能自己执行的如果你不调用就永不执行!

示例程序:

Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1})
Counter({33: 2, 22: 2, 11: 1, 44: 1})
{'builtins': <module 'builtin' (built-in)>, 'file': '/home/oldboy_py/Day3/coll.py',
'package': None,
'collections': <module 'collections' from '/usr/lib/python2.7/collections.pyc'>,
'c2': Counter({33: 2, 22: 2, 11: 1, 44: 1}),
'name': 'main',
'c1': Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1}),
'li': [11, 22, 33, 44, 33, 22],
'doc': None,
'str1': 'helloworld'}

各部分说明:

vars() =当前模块的所有变量
file 文件路径
doc 注释
name 被执行脚本的name属性等于main –>> name =
main’ 用于标示程序入口文件

自定义函数
导入的模块

内置函数

内置函数图

算术运算类

cmp() 比较
abs() 求绝对值
bool() 布尔值
divmod() 相除求商取余
max() 求一组数的最大值
min() 求一组数的最小值
sum() 求和
pow() 次方
len() 长度
all() 接受一个序列,判断,所有值为真(不为空),返回真 否则返回假
any() 一个是真就返回True
#转换类
chr() ascii 接受一个数字返回ascii字符
ord() 接收一个ascii字符返回数字
hex() 十六进制
oct() 八进制
bin() 二进制
#生成器
range()
xrange()
enumerate() 枚举函数 标示下标编号 默认从0开始 可以定义数字起始值
apply()
map()遍历序列,对序列中每个元素进行操作,最终获取新的序列。
filter()对于序列中的元素进行筛选,最终获取符合条件的序列
reduce()对于序列中的元素进行筛选,最终获取符合条件的序列

any()示例代码

>>> li = ['eric','',18]
>>> all(li)
False
>>> any(li)
True

自定义函数

前置条件

在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:

while True:
if cpu利用率 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接

if 硬盘使用空间 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接

if 内存占用 > 80%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接

上面的代码是就面向过程的编程,但是如果报警多了的话成百的代码需要添加如何操作呢?复制粘贴那会死人的!在看下下面的代码:

def 发送邮件(内容)
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接

while True:

if cpu利用率 > 90%:
发送邮件('CPU报警')

if 硬盘使用空间 > 90%:
发送邮件('硬盘报警')

if 内存占用 > 80%:
发送邮件('ram报警')

第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别:

  • 面向过程:更具需求一行一行垒代码!逻辑乱、并切代码重复、不易修改重用性差!
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

函数式编程

函数式编程最重要的是增强代码的重用性和可读性:

def 函数名(参数):

...
函数体
...

  • def:表示函数的关键字
  • 函数名:函数的名称,日后根据函数名调用函数
  • 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
  • 参数:为函数体提供数据
  • 返回值:当函数执行完毕后,可以给调用者返回数据。

.

1.返回值

函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。

  • 未明确指定返回值,则返回None
  • 返回值可以赋给某个变量 defemail(xxx) result = email()

.

def 发送短信():

发送短信的代码...

if 发送成功:
return True
else:
return False

while True:

# 每次执行发送短信函数,都会将返回值自动赋值给result

# 之后,可以根据result来写日志,或重发等操作

result = 发送短信()
if result == False:
记录日志,短信发送失败...

2.参数

为什么要有参数?看下下面的例子:

定义参数,用函数的话:

def 发送邮件(邮件内容)

发送邮件提醒

连接邮箱服务器
发送邮件
关闭连接

while True:

if cpu利用率 > 90%:
发送邮件("CPU报警了。")

if 硬盘使用空间 > 90%:
发送邮件("硬盘报警了。")

if 内存占用 > 80%:
发送邮件("内存报警了。")

函数的有三中不同的参数:

  • 普通参数
  • 默认参数
  • 动态参数

普通参数

定义函数

def func(name):
print name

执行函数

'lily' 叫做函数func的实际参数,简称:实参
func('lily')

默认参数

在你没有给他指定参数的时候他就会使用默认的参数!

def func(name, age = 18):

print "%s:%s" %(name,age)

指定参数

func('lily', 19)
# 使用默认参数
func('lily')

注:默认参数需要放在参数列表最后,要不就会报错!原因是:他的参数赋值是一个一个的赋值。如果提供了默认值的形参,你默认一定要往后排序为了就是你给那些没有陪默认值的参数 !

动态参数

动态参数顾名思义就是可以动态的去扩展函数参数的数量!

例子:1 (多个单个变量,整合成元组)

def func(*args):
print args

执行方式一

func(11,33,4,4454,5)
#输出结果:11,33,4,4454,5

执行方式二

li = [11,2,2,3,3,4,54]
func(li)
#输出结果:([11,2,2,3,3,4,54])

如果想输入的列表,不想让列表称谓元组里的仅一个元素而是让列表的元素成为元组的元素加*即可

func(*li)
#输出结果:(11,2,2,3,3,4,54)

1、接受多个参数
2、内部自动构造元组
3、序列,*,避免内部构造元组

例子:2(整合为字典变量)

def func(**kwargs):

print args

执行方式一

func(name='luotianshuai',age=18)

执行方式二

li = {'name':'luotianshuai', age:18, 'gender':'male'}
func(**li)

例子:3(整合了*args,**args)

def func(*args, **drgs):

print args
print dargs
#例子:
func(11,22,33,44,k1='luotianshuai',k2='shuaige')
(11, 22, 33, 44)

特别说明:

def func(arg):
print arg
#传入参数整合为元组,传入多少值都可以 传入
星号避免构造元组

def func(kwargs)
print kwargs
#
构造字典 func(***dic)只认字典

.

扩展:发邮件实例

形式参数 def email(message): message是形式参数
实际参数 email(“CPU出问题了”) “CPU出问题了”是实际参数
参数可以有n个,传入指定个数的参数
默认参数 def email(message,subject=“老男孩报警系统”)
1不传则使用默认值
2默认参数必须放在参数的最后边

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

def email(message):
msg = MIMEText("邮件报警测试", 'plain', 'utf-8')
msg['From'] = formataddr(["john",'john@test.com']) #发件人和发件邮箱
msg['To'] = formataddr(["tom",'10000@qq.com'])
msg['Subject'] = 小男孩报警系统 #这里我调用了参数

server = smtplib.SMTP("smtp.test.com", 25)
server.login("john@126.com", "john_emailpass")
server.sendmail('john@126.com', ['10000@qq.com',], msg.as_string())
server.quit()

if name == u'main':
cpu = 100
disk = 500
ram = 50
for i in range(1):
if cpu > 90:
alert = u'CPU出问题了' #这里设置了一个变量
email(alert) #这里调用函数的时候引用了上面的变量,当执行函数的时候形参讲会被替换掉,message='CPU出问题了' 发送邮件!
if disk > 90:
alert = u'硬盘出问题了'
email(alert)
if ram> 80:
alert = u'内存出问题了'
email(alert)

return参数

def count():
for i in range(1,10):
if i = 5:
return
else:
print i
print "Hello World"
#所以当i=5的时候就直接跳出了函数了,这里是不会被打印出来了!不是循环!!!
count()

输出结果:
2
4

return 一般写在函数的末尾,一般你想看函数的执行结果!然后判断后面的程序。看下面的例子

def count():
name = "john"
for i in range(1,10):
if i == 5:
print "hello"
else:
print i
return name
#在这里加了一个return
user = count()
if user == "john": #然后判断,看下执行结果!
print "oh john is coming"

执行结果:
2
4
hello
7
9
oh john is coming
#这里看下! 上面的判断执行了!所以return这个把name的值输出了!

文件操作

打开文件

文件句柄 = file('文件路径', '模式')
#python中打开文件有两种方式,即:open(...) 和 file(...) ,本质上前者在内部会调用后者来进行文件操作,推荐使用 open。3.0以后file方法讲被用做其他,open方法会自动的去帮你找他调用得方法在那里!

打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。

打开文件的模式有:

  • r,只读模式(默认)。
  • w,只写模式。【不可读;不存在则创建;存在则删除内容;】
  • a,追加模式。【可读; 不存在则创建;存在则只追加内容;】

"+" 表示可以同时读写某个文件

  • r+,可读写文件。【可读;可写;可追加】
  • w+,无意义
  • a+,同a

"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

  • rb
  • wb
  • ab

"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)

  • rU
  • r+U

文件操作

class file(object):

def close(self): # real signature unknown; restored from doc
关闭文件
"""
close() -> None or (perhaps) an integer. Close

def fileno(self): # real signature unknown; restored from doc
文件描述符

def flush(self): # real signature unknown; restored from doc
刷新文件内部缓冲区
""" flush() -> None. Flush the internal I/O buffer. """
pass

def isatty(self): # real signature unknown; restored from doc
判断文件是否是同意tty设备

def next(self): # real signature unknown; restored from doc
获取下一行数据,不存在,则报错

def read(self, size=None): # real signature unknown; restored from doc
读取指定字节数据

def readinto(self): # real signature unknown; restored from doc
读取到缓冲区,不要用,将被遗弃

def readline(self, size=None): # real signature unknown; restored from doc
仅读取一行数据

def readlines(self, size=None): # real signature unknown; restored from doc
读取所有数据,并根据换行保存值列表

def seek(self, offset, whence=None): # real signature unknown; restored from doc
指定文件中指针位置

def tell(self): # real signature unknown; restored from doc
获取当前指针位置

def truncate(self, size=None): # real signature unknown; restored from doc
截断数据,仅保留指定之前数据

def write(self, p_str): # real signature unknown; restored from doc
写内容

def writelines(self, sequence_of_strings): # real signature unknown; restored from doc
将一个字符串列表写入文件

def xreadlines(self): # real signature unknown; restored from doc
可用于逐行读取文件,非全部

with方法

为避免打开文件后忘记关闭,可以通过管理上下文,即:(建议使用此方法打开文件)
with 还支持同时打开多个文件 python2.7+支持

with open('log','r') as f:

...
用法示例

with open('nginx.conf','r') as read_obj,open('nginx.conf.new','w') as write_obj:
for i in read_obj.readlines():
i = i.strip()
print i
write_obj.write(i)
write_obj.write('\n')
#逐行读出一个文件后for循环它,并写回回一个新文件

posted @ 2015-12-05 16:47  hallo.world  阅读(128)  评论(0)    收藏  举报