Python
函数
•
函数就是完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取一个名字。
•
可以通过函数名在程序的不同地方多次执行(这通常叫函数调用)。
•
预定义函数
可以直接使用
•
自定义函数
用户自己编写
•
为什么使用函数
•
降低编程难度
-
通常将一个复杂的大问题分解成一系列的小问题,然后将小问题划分成更小的问题,当问题细化为足够简单时,我们就可以分而治之。各个小问题解决了,大问题就迎刃而解了。
•
代码重用
-
避免重复劳作,提供效率
•
函数的定义和调用
- def
函数名
([
参数列表
]): //
定义 ##函数名规则跟变量一样,但是多个单词,除了第一个单词后面单词的首字母都要大写,单词之间可以用下划线连接
-
函数名
([
参数列表
]) //
调用
def fun ():
print 'hello'
fun() ##调用
小练习:
1、#!/usr/bin/python
def fun(): ##定义一个函数
sth = raw_input('please input a number: ') ##将键盘输入赋值给一个变量
try: ##try except 为抓取异常函数, 如果int(字符串) 的话程序会报错,就是将此次错误抓出来,当成一个条件,except后面执行错误情况下的输出。
if type(int(sth))==int:
print "%s is a number"%sth
except ValueError: ##在valueerror的情况下才会执行以下代码
print "%s is not a number"%sth
fun() ##调用函数
函数参数
•
形式参数和实际参数
-
在定义函数时,函数名后面括号中的变量名称叫做“形式参数”,或者称为“形参”
-
在调用函数时,函数名后面括号中的变量名称叫做“实际参数”,或者称为“实参”
def fun (x,y): xy是形参
print x*y
调用 fun(1,2)##12是实参
练习
1、判断输入的是否是数字,sys模块
#!/usr/bin/python
import sys ##调用sys模块
def isNum(s):
for i in s:
if i in '0123456789':
pass
else:
print '%s is not a number'% s
sys.exit()
else:
print "%s is a number"%s
isNum(sys.argv[1]) ##sys.argv方法,输出脚本名称,和带入的所以的赋值。 参数1表示第一个赋值
2、•
打印系统的所有
PID
•
要求从
/proc
读取。
•
os.listdir() ###参数是一个路径,返回的是文件中的内容的字符串。查看目录中所以文件,不包括隐藏文件
#!/usr/bin/python
import os
import sys
def fun(s): 定义函数
for i in s :
if i in '1234567890':
pass
else:
break
print s ###打印出纯数字的名字
for i in os.listdir('/proc'): ##遍历文件夹中的文件
fun (i) ##调用函数
函数默认参数
•
缺省参数(默认参数)不赋值的话,按照默认参数执行
def fun(x, y=100):
print x,y
fun(1,2) ==200
fun(1) ==100
fun(x=20,y=10)
Python函数变量
局部变量和全局变量
- Python中的任何变量都有特定的作用域
- 在函数中定义的变量一般只能在该函数内部使用,这些只能在程序的特定部分使用的变量我们称之为局部变量。。 只能在函数内部有效,外部无效。
- 在一个文件顶部定义的变量可以供文件中的任何函数调用,这些可以为整个程序所使用的变量称为全局变量
global语句
- global 变量名
强制声明为全局变量
练习
1、
#!/usr/bin/python
x=200
def fun():
x=100
print x
此程序输出是200的全局变量,而不是100的局部变量,函数执行完毕,局部变量就会销毁
2、
x=100
def fun():
x+=1 ## 不能在全局变量,做一些改变操作
print x
fun() ##必须调用,不调用函数是不执行的。
3、global语句:改变变量的所属区域
①把全局变量可在函数内进行更改
#!/usr/bin/python
x=100
def fun():
global x ###global声明x以后,可对全局变量进行操作更改
x +=1 ##
print x 输出101
fun ()
print x 输出101
两个print的输出都是101
②把局部变量声明为全局变量
#!/usr/bin/python
def fun ():
global y ##声明局部变量y为全局变量。如果此处不声明,则执行报错:没有声明变量y。
y=1
fun()
print y
4、print locals 的用法
#!/usr/bin/python
def fun ():
x=1
y=1
print locals() ##将函数内所有的变量以字典的形式打印出来
fun()
print locals () ##将脚本里面的所有变量以字典的形式打印出来,包括python系统自定义变量
Python函数返回值
函数返回值
- 函数被调用后会返回一个指定的值
- 函数调用后默认返回None
- return 返回值
- 返回值可以是任意类型
- return执行后,下面就不再执行(类似与break)
- return与print区别
a.isdigit() 用法 判断a是否为纯数字
练习
1、#!/usr/bin/python
def fun():
print 'hello world'
print fun() ##输出结果为hello world +none 。这个none就为函数的返回值,默认为none。
2、#!/usr/bin/python
def fun():
print 'hello world'
return 1 ##指定了返回值为1.函数碰到return 则局部函数结束 ,后面有其他语句,不执行。
print fun() ##输出结果就为hello world +1
3、利用return值,打印出所以的pid
#!/usr/bin/python
import os
def fun(s):
for i in s:
if i not in '0987654321':
return False ##不是数字 返回错误,同时终止if
return True ##其他都返回true
for i in os.listdir('/proc'):
if fun(i): ## if true则继续执行
print i
4、
#!/usr/bin/python
import os
def fun(s):
if s.isdigit(): 判断其是否为纯数字。
return True #终端当前判断
return False ##中断当前判断
for i in os.listdir('/proc'):
if fun(i): ## if true
print i
~
Python函数冗余参数
多类型传值 传参的时候,参数的个数必须一致
冗余参数
向函数传元组和字典
处理多余实参
def fun(x,y,*args,**kwargs)
小练习:
1、元组传参
def fun(x,y):
return x+y
fun (3,4) ##直接对应赋值
t=(3,4)
fun(*t) ##直接带入星号+变量
def fun(x,y,z):
return x+y+z
fun (1,2,3)
fun(a=1,b=2,c=3)这是错误的调用方法,应该变量名字一致
fun(x=1,y=2,z=3)
fun(*(1,2,3))
fun(1,*t)
fun(*t,1)##这种输入方法不可,有语法错误。
2、字典传参
t={'x':1,'y':2,'z':3}
fun(**t)
3、要冗余参数
def fun(x,*args,**kwargs):
...: print x
...: print args
...: print kwargs
fun (1,2,'aa',y=2,*t,**{'c':1})
1
(2, 'aa')
{'y': 2}
第一个参数赋值x
中间的元组,列表,字符串赋值到元组中
最后的等式赋值到字典中
必须按顺序赋值
Python
函数递归调用
函数内部自己调用自己
计算阶层
•
普通方法:
-
使用循环
#!/usr/bin/python
def fun (n):
sum =1
for i in xrange(1,n+1):
sum *=i
return sum
print fun(100)
•
递归调用
•
def factorial(n):
•
if n == 0: ##最后默认结果 返回1,不能0 乘以0就没了(返回的是最后位数)
•
return 1
•
else:
•
return n * factorial(n-1) :递归参数必须向默认结果收敛
•
•
print factorial(5)
递归的注意事项
•
必须有最后的默认结果
if n == 0
•
递归参数必须向默认结果收敛的:
factorial(n-1)
打印目录下所有文件
•
def print_files(path):
•
isdir, isfile, join = os.path.isdir, os.path.isfile, os.path.join
•
lsdir = os.listdir(path)
•
dirs = [i for i in lsdir if isdir(join(path,i))]
•
files = [i for i in lsdir if isfile(join(path,i))]
•
if dirs:
•
for d in dirs:
•
print_files(join(path,d))
•
if files:
•
for f in files:
•
print join(path,f)
•
print_files(sys.argv[1])
os.path.isdir('/home') 判断是否是目录,不存在返回错误
os.path.isfile('./1.py') 判断是否是文件,不存在返回错误
os.path.join('/etc/','password','abc') 连接路径的作用,会把字符串当作路径,最后当作文件
输出:'/etc/password/abc'
#!/usr/bin/python
import os
import sys
def print_files(path):
lsdir = os.listdir(path) ##打印出下级目录的下的所有
dirs =[i for i in lsdir if os.path.isdir(os.path.join(path,i))] ##判断文件
files=[i for i in lsdir if os.path.isfile(os.path.join(path,i))] ##判断目录
if files:
for j in files:
print os.path.join(path,j) ##文件打印
if dirs:
for d in dirs:
print_files(os.path.join(path,d)) ##目录递归
print_files(sys.argv[1]) ##打印所有文件
把目录的判断放在前面,先打印出来的是最深层次的文件。
Python
函数
lambda
•
匿名函数
- lambda
函数是一种快速定义单行的最小函数,可以用在任何需要函数的地方。
•
def fun(x, y):
return x*y
fun(2, 3)
•
r = lambda x,y: x*y ##返回的是个函数对象,需要有一个变量去接收
r(2, 3)
•
匿名函数优点:
- 1.
使用
python
写一些脚本时,使用
lambda
可以省去定义函数的过程,让代码更加精简。
- 2.
对于一些抽象的,不会被别的地方再重复使用的函数,有时候函数起个名字也是个难题,使用
lambda
不需要考虑命名的问题。
- 3.
使用
lambda
在某些时候让代码更容易理解。
lambda
基础
•
lambda
语句中,冒号前是参数,可以有多个,逗号隔开,冒号右边是返回值。
•
lambda
语句构建的其实是一个函数对象
lambda
使用
reduce(lambda x,y:x+y,[1,2,3,4,5]) ==1+2+3+4+5=15
reduce(lambda x,y:x+y,xrange(1,6))
reduce的用法
•
def add(x, y):
return x + y
sum = reduce(add, [1, 2, 3])
•
•
reduce(lambda x,y:x+y, range(1,4))
Python内置函数
例子
__builtin__.
tab就会出来所有内置的类和函数,类的首字母是大写,函数第二个字母才是大写,或者help查看
返回数字的绝对值
取列表最大最小值
也可以在官网https://docs.python.org/2/library来查询所有函数的使用方法
常用函数
绝对值
自建函数绝对值
def fun(x):
if x <0:
return -x
return x
内置函数的绝对值方法:
abs(-10)==10
最大最小值
max[(1,2,3,4)]/max('1234') /min([1,2,3,4])
abs() ##绝对值
max()
min()
len() ##求序列的长度,字符串,列表,元组都可以用。
divmod() ##divmod(5,2) 输出(2,1),输出(商,余数)
pow() ##pow(x,y)==x**y 、poe(x,y,z)==(x**y)%z
round() ##round(x,y) 四舍五入x,小数点后保留y位
callable() ##测试函数是否可被调用,返回正确或者错误(布尔值)
type() ##对象的类型
isinstance() ##判断对象是否是给定类型的 isinstance(对象,(多个类型也可以,也可是具体的值比如具体的元组)类型)
cmp() ##
比较两个序列是否相等 x<y 返回-1 x==y 返回0 x>y 返回1。如果是字符串,(就像新华字典的排字顺序,越前越大)
range() ##迭代
xrange() ##迭代对象
类型转换函数
int() ##整形
long() ##长型
float() ##浮点
complex() ##复数
str() ##字符串
list() ##列表 。
tuple() ##元组
hex() ##16进制,把int变成16进制的字符串
oct() ## 8进制
chr() ##将0-255的数字转化为阿司科码字符
ord() ##与chr相反,将阿斯克吗字符转化为数字
eval() ##将字符串,列表(用双引号)当成有效的表达式来求值
字符串处理函数 (也可以叫做字符串的方法)
str.capitalize() ##字符串的首字母大写,无参数
str.replace() ##(old,new,[次数]) 默认将字符串中的所有旧的字符替换,可限制替换次数
str.split() ##默认以空格(换行\n,tab\t)将字符串切分为列表。([分隔符],[最大切分几次])
str.join() ##字符串连接 ''.join(str(i) for i in range(10)) 输出‘0123456789’
string模块
import string 调用string模块
string.lowercase ##打印所有小写的
string.uppercase ##打印所有大写的
string.capitalize##首字母大写(‘hello’) 输出Hello
string.replace ##(old,new,[替换几次 ]) (‘hello’,‘o’,‘0’)
序列处理函数
len()
max()
min()
filter() 过滤
filter(None,range(10)) 不做任何处理,直接返回 [1, 2, 3, 4, 5, 6, 7, 8, 9]
def fun(x):
....: if x %2 !=0:
....: return True
filter(fun,range(10)) 返回[1, 3, 5, 7, 9] 对序列进行函数调用返回奇数
zip() ##把两个或者多个小列表合成大列表,像拉链一样。如果列表的长度不一样,结果是取最小的。
map(None,l1,l2,l3)
当参数为None时候,功能类似于filter,当某个列表长度较小时,不足的元素用none填充。
当参数为函数的时候,后面调用前面函数
reduce()调用函数执行后面的迭代
def =f(x,y):
return x+y
reduce(f,range(1,101))
使用lambda 隐藏函数(匿名函数)
filter(lambda x:x %2 ==0, range(10))
[0, 2, 4, 6, 8]
map(lambda x,y:x*y, range(5),range(5))
[0, 1, 4, 9, 16]
reduce(lambda x,y:x+y, range(1,101))
5050
列表表达式
[i*2+10 for i in range(10)]
[i for i in range(10) if i%3 == 0]
Python模块使用
模块是Python组织代码的基本方式。
一个Python脚本可以单独运行,也可以导入到另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module)。
所有的.py文件都可以作为一个模块导入
模块名与脚本的文件名相同
例如我们编写了一个名为hello.py的脚本,则可以在另一个脚本中用import hello语句来导入它。
但是,模块的名字命名规则跟变量是一样的,不能以数字打头。
包
Python的模块可以按目录组织为包
创建一个包的步骤:
- 创建一个名字为包名的目录
- 在该目录下创建一个__init__.py文件 ##必须有此文件python才可以把它识别为 包
- 根据需要,在该目录下存放脚本文件或已编译的扩展及子包
- import pack.m1, pack.m2, pack.m3 ##import.包名.模块名,或者import.包名
python path/python模块的位置
sys.path sys模块的path属性
查看所有模块的位置的顺序,输出的内容如下,按照以下顺序寻找模块的位置
['',
'/usr/bin',
'/usr/lib/python2.6/site-packages/AliyunUtil-0.0.1-py2.6.egg',
'/usr/lib/python2.6/site-packages/cloud_init-0.7.6-py2.6.egg',
'/usr/lib/python2.6/site-packages/jsonpatch-1.15-py2.6.egg',
'/usr/lib/python2.6/site-packages/requests-2.13.0-py2.6.egg',
'/usr/lib/python2.6/site-packages/argparse-1.4.0-py2.6.egg',
'/usr/lib/python2.6/site-packages/Jinja2-2.9.5-py2.6.egg',
'/usr/lib/python2.6/site-packages/jsonpointer-1.10-py2.6.egg',
'/usr/lib/python2.6/site-packages/six-1.10.0-py2.6.egg',
'/usr/lib64/python26.zip',
'/usr/lib64/python2.6', ##大部分模块的路径都在这里
'/usr/lib64/python2.6/plat-linux2',
'/usr/lib64/python2.6/lib-tk',
'/usr/lib64/python2.6/lib-old',
'/usr/lib64/python2.6/lib-dynload',
'/usr/lib64/python2.6/site-packages',
'/usr/lib/python2.6/site-packages',
'/usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info',
'/usr/lib/python2.6/site-packages/IPython/extensions']
rpm -ql python-libs ##通过rpm命令查看python相关的包
小实验:
创建一个包
除了默认的python path(python 路径)之外,我们还有自定义的PYTHONPATH
export PYTHONPATH
mkdir /root/library ##创建一个目录
两种方法,将此目录变成python的目录
第一,sys.path.append('/root/library/') 用sys模块的path。append方法将路径加到所以路径的最后面。只能在当前的ipython生效
第二,修改系统的环境变量 vim /root/.bashrc 修改root路径下的.bashrc
在文档的最末尾加上
export PYTHONPATH=/root/library ##如果有多个路径,用冒号分开
然后执行下 . /root/.bashrc 让环境变量生效,只能在当前终端生效。
然后就会发现此变量就会在路径的最上面
小实验:
mkdir /root/bao
vim /root/bao/m1.py
#!/usr/bin/python
def wordCount(s):
chars = len(s) ##统计字符
words = len(s.split()) ##统计单词,以单词的形式切分
lines = len(s.split('\n')) ## 统计行数,以换行符来切分, 此种方法切割,最后会多出一个字符串
###lines = s.count('\n') 统计有几个换行符,此种方法比较好。
print lines, words, chars
s = open('/etc/passwd').read()
wordCount(s)
调用的时候import bao.m1 即可调用此个脚本
将路径放在pathon的脚本路径中 就可直接调用模块 sys.path.append('/root/bao/')
import m1 就可以直接调用
总结
模块是一个可以导入的Python脚本文件;
包是一些按目录组织的模块和子包,目录下有__init__.py文件,此文件可以存放包的信息;
导入模块和包的语法:
- import , import as
- from … import …
Python
面向对象
•
类和对象
•
Python
类定义
•
类属性
•
类方法
•
面向过程和面向对象编程
-
面向过程编程:函数式编程,
C
程序等
-
面向对象编程:
C++,Java,Python
等
•
类和对象:是面向对象中的两个重要概念
-
类:是对事物的抽象,比如:人类、球类
-
对象:是类的一个实例,比如
:
足球、篮球
•
实例说明:
-
球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来。
为什么面向对象
•
面向对象的主要思想是:
-
封装
-
继承
-
多态
•
这种思想方便解决较为复杂的项目,且维护起来较为容易。
Python
类定义
•
类定义:
类把需要的变量和函数组合成一起,这种包含称为“封装”
class A(object):
•
类的结构:
class
类名
:
成员变量
–
属性
成员函数
–
方法
类的创建
•
class MyClass(object):
def fun(self):
print “I am function”
•
类的方法中至少有一个参数
self
类的组成
•
类由属性和方法组成,类的属性是对数据的封装,类的方法是对类的行为的封装。
-
成员变量
--
静态属性
-
成员函数
--
动态方法
对象的创建
•
创建对象的过程称之为实例化;当一个对象被创建后,包含三个方面的特性:对象句柄、属性和方法。
句柄用于区分不同的对象
对象的属性和方法与类中的成员变量和成员函数对应
•
obj = MyClass() //
创建类的一个实例
(
对象
)
通过对象来调用方法和属性
类的属性
•
类的属性按使用范围分为公有属性和私有属性,类的属性范围取决于属性的名称。
•
-
公有属性
:在类中和类外都能调用的属性。
-
私有属性
:不能在类外及被类以外的函数调用。
定义方式:以
”__”
双下划线开始的成员变量就是私有属性
可以通过
instance._classname__attribute
方式访问。
-
内置属性
:由系统在定义类的时候默认添加的,由前后双下划线构成,
__dict__, __module__
。
类的方法
•
方法的定义和函数一样,但是需要
self
作为第一个参数。
•
类方法为:
-
公有方法
-
私有方法
-
类方法
-
静态方法
•
公有方法
:在类中和类外都能调用的方法。
•
私有方法
:不能被类的外部调用,在方法前面加上
”__”
双下划线就是私有方法。
•
self
参数
用于区分函数和类的方法(
必须有一个
self)
,
self
参数表示执行对象本身。
•
类方法
:被
classmethod()
函数处理过的函数,能被类所调用,也能被对象所调用
(
是继承的关系
)
•
静态方法
:相当于
”
全局函数
”
,可以被类直接调用,可以被所有实例化对象共享,通过
staticmethod()
定义,
静态方法没有
”self”
参数。
•
装饰器:
- @classmethod
- @staticmethod
Python
内部类
•
所谓内部类,就是在类的内部定义的类,主要目的是为了更好的抽象现实世界。
•
例子:
汽车是个类,汽车的底盘,轮胎也可以抽象为类,将其定义到汽车类中,则形成内部类,更好的描述汽车类,因为底盘、轮胎是汽车的一部分。
•
内部类的实例化方法
•
方法
1
:直接使用外部类调用内部类
object_name = outclass_name.inclass_name()
•
方法
2
:先对外部类进行实例化,然后再实例化内部类
out_name = outclass_name()
in_name = out_name.inclass_name()
in_name.method()
魔术方法
•
__str__(self)
•
构造函数与析构函数
-
构造函数:
用于初始化类的内部状态,
Python
提供的构造函数是
__init__()
;
__init__()
方法是可选的,如果不提供,
Python
会给出一个默认的
__init__
方法
-
析构函数:
用于释放对象占用的资源,
Python
提供的析构函数是
__del__();
__del__()
也是可选的,如果不提供,则
Python
会在后台提供默认析构函数
垃圾回收机制
•
Python
采用垃圾回收机制来清理不再使用的对象;
python
提供
gc
模块释放不再使用的对象。
•
Python
采用
”
引用计数
”
的算法方式来处理回收,即:当某个对象在其作用域内不再被其他对象引用的时候,
python
就自动清除对象;
•
gc
模块的
collect()
可以一次性收集所有待处理的对象
(gc.collect)
类的继承
•
继承是面向对象的重要特性之一;
•
继承关系:继承是相对两个类而言的父子关系,子类继承了父类的所有
公有属性和方法
•
继承实现了代码重用。
使用继承
•
继承可以重用已经存在的数据和行为,减少代码的重复编写。
Python
在类名后使用一对括号来表示继承关系,括号中的类即为父类。
•
class Myclass(ParentClass)
如果父类定义了
__init__
方法,子类必须显式调用父类的
__init__
方法:
ParentClass.__init__(self, [args…])
如果子类需要扩展父类的行为,可以添加
__init__
方法的参数。
例子
•
class Parent(object):
def fun(self):
print “
我是父类
”
class MyClass(Parent):
def func(self):
print “
我是子类
”
•
test = MyClass()
test.fun()
test.func()
继承父类
•
class A:
•
def __init__(self):
•
print "enter A"
•
print "leave A"
•
•
class B(A):
•
def __init__(self):
•
print "enter B"
•
A.__init__(self)
•
print "leave B"
•
•
b = B()
super
函数
•
class A(object):
•
def __init__(self):
•
print "enter A"
•
print "leave A"
•
•
class B(A):
•
def __init__(self):
•
print "enter B"
•
super(B, self).__init__()
•
print "leave B"
•
•
b = B()
多重继承
•
Python
支持多重继承,即一个类可以继承多个父类;
•
语法:
class class_name(Parent_c1, Parent_c2,…)
•
注意:
当父类中出现多个自定义的
__init__
方法时,多重继承只执行第一个类的
__init__
方法,其他不执行。
类的属性
-
总结
•
类属性,也是共有属性
•
类的私有属性
•
对象的共有属性
•
对象的私有属性
•
内置属性
•
函数的局部变量
•
全局变量
类的方法
-
总结
•
公有方法
•
私有方法
•
类方法
•
静态方法
•
内置方法