python基础语法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础语法相关的知识,希望对你有一定的参考价值。
语言排行榜
https://www.tiobe.com/tiobe-index/
编码格式ascii/unicode/utf-8
1、unicode
In [11]: name=u"范特西"
In [12]: name
Out[12]: u‘\u8303\u7279\u897f‘
In [13]: print name
范特西
In [14]: type(name)
Out[14]: unicode
2、unicode转换为utf-8
In [15]: name.encode(‘utf-8‘)
Out[15]: ‘\xe8\x8c\x83\xe7\x89\xb9\xe8\xa5\xbf‘
In [16]: name_utf8=name.encode(‘utf-8‘)
In [17]: name_utf8
Out[17]: ‘\xe8\x8c\x83\xe7\x89\xb9\xe8\xa5\xbf‘
In [18]: len(name_utf8)
Out[18]: 9
In [21]: print ‘\xe8\x8c\x83‘
范
In [22]: print ‘\xe7\x89\xb9‘
特
In [23]: print ‘\xe8\xa5\xbf‘
西
注意:ascii可以作为unicode的子集;内存为unicode编码统一处理;为了节省硬盘空间,将unicode转换为utf-8;如果有中文需要 #_*_ coding:utf-8 _*_
In [25]: name_utf8=‘叶惠美‘
In [26]: name_utf8
Out[26]: ‘\xe5\x8f\xb6\xe6\x83\xa0\xe7\xbe\x8e‘
In [27]: name_unicode=u‘叶惠美‘
In [28]: name_unicode
Out[28]: u‘\u53f6\u60e0\u7f8e‘
In [29]: name_unicode.encode(‘utf-8‘)
Out[29]: ‘\xe5\x8f\xb6\xe6\x83\xa0\xe7\xbe\x8e‘
In [30]: name_utf8.decode(‘utf-8‘)
Out[30]: u‘\u53f6\u60e0\u7f8e‘
命令执行状态结果与执行结果
In [31]: import os
In [33]: cur_dir=os.system(‘pwd‘) ---执行状态结果
/root
In [34]: print cur_dir
0
In [35]: dir=os.popen(‘pwd‘).read() --- 执行结果
In [36]: dir
Out[36]: ‘/root\n‘
In [37]: import commands
In [38]: dir=commands.getstatusoutput(‘pwd‘) --- 执行结果
In [39]: dir
Out[39]: (0, ‘/root‘)
%s:接收任意输入,作为字符串处理;
%d:接收外部输入,必须为整数或者浮点数
流程控制
id及type(变量引用数据的id,类型,值)
>>> num=1
>>> id(num)
37322512
>>> name="tom"
>>> id(name)
41956248
>>>
>>> type(num)
<type ‘int‘>
>>> type(name)
<type ‘str‘>
>>>
实例被创建后,对象的id和类型无法修改;
值可以修改,为可变对象;不可修改,为不可变对象;
某个对象包含其他对象的引用,则称为容器;列表
数据的属性和方法
属性:内部可用的变量
方法:内部可用的函数,()运算符
对象引用:所有数据存放为内存对象;所有变量是指向内存的引用;变量名与数据单独存放;
name="tom" name -> tom
name="jerry" name -> jerry tom (不被引用时将自动删除,指针计数)
= 将变量名与数据进行绑定;如果存在,则直接绑定,否则先创建再绑定;
>>> test="tom"
>>> id(test)
41956248
>>> name
‘tom‘
>>> id(name)
41956248
>>>
变量区分大小写,只能包含字母、数字、下划线
命名规范:
1、以单一下划线开头(_x)不会被from module import * 导入
2、前后有双下划线(__x__)为系统变量,对python解释器有特殊意义
3、以两个下划线开头(__x)为类的本地变量
4、交互式模式下(常用于测试),变量名"_"用于保存最后表达式的结果
>>> 1+1
2
>>> print _
2
>>>
注:变量名(name)没有类型,数据对象才有类型;变量可以引用任意对象
>>> type(name)
<type ‘str‘>
>>> name=3.14
>>> type(name)
<type ‘float‘>
>>>
核心数据类型(python 一切皆对象,强类型语言):
数字:int,long,float,complex,bool
字符:str,unicode
列表:list
字典:dict
元组:tuple
文件:file
集合:set
类:class
None
其他文件类工具:pipes,fifos,sockets
类型转换:
非字符转换为字符:str(),repr()或format()
>>> num1=5.61
>>> type(num1)
<type ‘float‘>
>>> num2=repr(num1)
>>> type(num2)
<type ‘str‘>
>>> num3=format(num1)
>>> type(num3)
<type ‘str‘>
>>>
int():正数转换
float():浮点转换
>>> num1=45
>>> num2=float(num1)
>>> type(num1)
<type ‘int‘>
>>> type(num2)
<type ‘float‘>
>>>
list():将字串转换为列表
>>> str1="hello,world"
>>> l1=list(str1)
>>> print l1
[‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘,‘, ‘w‘, ‘o‘, ‘r‘, ‘l‘, ‘d‘]
>>> type(l1)
<type ‘list‘>
tuples():将字串转换为元组
>>> t1=tuple(str1)
>>> type(t1)
<type ‘tuple‘>
>>> print t1
(‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘,‘, ‘w‘, ‘o‘, ‘r‘, ‘l‘, ‘d‘)
>>>
set():将字串转换为集合,无序去重
>>> s1=set(str1)
>>> type(s1)
<type ‘set‘>
>>> print s1
set([‘e‘, ‘d‘, ‘h‘, ‘l‘, ‘o‘, ‘,‘, ‘r‘, ‘w‘])
>>>
frozenset():将字串转换为不可变集合
dict():根据key-value元组序列,创建字典;
>>> l1=[(‘a‘,1),(‘b‘,11),(‘c‘,45)]
>>> print l1
[(‘a‘, 1), (‘b‘, 11), (‘c‘, 45)]
>>> d1=dict(l1)
>>> print d1
{‘a‘: 1, ‘c‘: 45, ‘b‘: 11}
>>>
chr():将整数按ascii码转换为字符
>>> num2=77
>>> type(num2)
<type ‘int‘>
>>> c1=chr(num2)
>>> print c1
M
>>> type(c1)
<type ‘str‘>
>>>
ord():将字符转换为整数值
hex():将整数转换为16进制字符串
bin():将整数转换为2进制字符串
oct():将整数转换为8进制字符串
>>> x=16
>>> str=hex(x)
>>> print str
0x10
>>> str=bin(x)
>>> print str
0b10000
>>> str=oct(x)
>>> print str
020
>>> type(str)
<type ‘str‘>
>>>
数字操作符:
位移:>> 或 <<
>>> str=bin(x)
>>> print str
0b10000
>>> str=bin(x>>2)
>>> print str
0b100
逻辑与:&
>>> 1&0
0
>>> 1&1
1
>>>
逻辑或:|
>>> 1 | 1
1
>>> 1 | 0
1
>>> 0| 0
0
>>>
异或:^
>>> 1^0
1
>>> 1^1
0
取反:~
>>> 101
101
>>> ~101
-102
>>> num=101
>>> num1=101
>>> num2=-102
>>> print (bin(num1))
0b1100101
>>> print (bin(num2))
-0b1100110
>>>
文档字串:
>>> def printName():
... "test function"
... print "hello,world"
...
>>> printName() (()表示调用运算符,调用函数)
hello,world
>>> printName.__doc__ (不加()引用对象)
‘test function‘
>>> printName().__doc__
hello,world
>>>
>>> dir(printName)
[‘__call__‘, ‘__class__‘, ‘__closure__‘, ‘__code__‘, ‘__defaults__‘, ‘__delattr__‘, ‘__dict__‘, ‘__doc__‘, ‘__format__‘, ‘__get__‘, ‘__getattribute__‘, ‘__globals__‘, ‘__hash__‘, ‘__init__‘, ‘__module__‘, ‘__name__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘func_closure‘, ‘func_code‘, ‘func_defaults‘, ‘func_dict‘, ‘func_doc‘, ‘func_globals‘, ‘func_name‘]
>>> dir(printName())
hello,world
[‘__class__‘, ‘__delattr__‘, ‘__doc__‘, ‘__format__‘, ‘__getattribute__‘, ‘__hash__‘, ‘__init__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘]
>>>
for循环比while循环执行速度快;
python中提供两个内置函数range或xrange,用于定制for循环中特殊的循环
range:一次性返回连续的整数列表;
xrange:一次性产生一个数据元素,相对于range更节约内存空间;
In [55]: sum=0
In [56]: for i in range(1,101):
....: sum+=i
....: else:
....: print sum
....:
5050
In [57]: for i in xrange(1,101):
sum+=i
else:
print sum
....:
10100
range用法:非完备遍历(用于指定长度挑选元素);修改列表
In [5]: for i in range(0,len(s),2):
print s[i],
...:
h w a e y u i e t a k y u
In [6]: s="how are you, fine thank you"
In [8]: l1=[1,2,3,4,5]
In [9]: for i in range(len(l1)):
...: l1[i]+=1
...: else:
...: print l1
...:
[2, 3, 4, 5, 6]
zip:取得一个或多个序列为参数,将给定序列中的并排的元素配成元组,返回这些元组的列表;当长度不同时,zip会以最短的序列长度为准
zip用法:可在for循环中用于实现并行迭代;zip常用于动态创造字典
In [12]: l2=[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘]
In [13]: l1=[1,2,3,4,5,6,7]
In [14]: zip(l1,l2)
Out[14]: [(1, ‘a‘), (2, ‘b‘), (3, ‘c‘), (4, ‘d‘), (5, ‘e‘), (6, ‘f‘), (7, ‘g‘)]
In [15]: keys=[1,2,3,4,5,6,7]
In [16]: values=[‘mon‘,‘tus‘,‘wed‘,‘thu‘,‘fri‘,‘sat‘,‘sun‘]
In [17]: d={}
In [19]: for (k,v) in zip(keys,values):
d[k]=v
else:
....: print d
....:
{1: ‘mon‘, 2: ‘tus‘, 3: ‘wed‘, 4: ‘thu‘, 5: ‘fri‘, 6: ‘sat‘, 7: ‘sun‘}
字符串常见运算符:
[i]:索引运算符
[i:j]:切片运算
[i:j:stride]:扩展切片
切片结果将生成一个新内存对象;
字符串操作
>>> str="xiong chen"
>>> str[0:]
‘xiong chen‘
>>> str[0:5]
‘xiong‘
>>> str[6:0:-1]
‘c gnoi‘
>>> str[9]
‘n‘
>>> str[-1]
‘n‘
In [2]: str="xiong chen"
In [3]: str[-3::-1]
Out[3]: ‘hc gnoix‘
In [4]: str[5::-1]
Out[4]: ‘ gnoix‘
In [5]:
sum只适用于数字序列
In [5]: l1=[1,2,3,4]
In [6]: sum(l1)
Out[6]: 10
In [7]:
字符串常用方法
s.capitalize():首字符大写
>>> msg="what‘s your name?"
>>> msg.find(‘name‘)--- 从左往右查找
12
>>> msg.find(‘your‘)
7
>>> msg.find(‘cxiong‘)
-1
>>>
In [11]: str.capitalize()
Out[11]: ‘Xiong chen‘
s.index(sub):找到指定字符串sub首次出现的位置,找不到返回valueError异常
In [9]: ‘‘.join(l2)
Out[9]: ‘xiong chen‘
In [13]: str.index(‘c‘)
Out[13]: 6
>>> msg.split() --- 以空格分隔,字符串转换为列表
["what‘s", ‘your‘, ‘name?‘]
s.join(t):s作为分隔符,连接序列t中的字符串
In [7]: l2=list(str)
In [8]: print l2
[‘x‘, ‘i‘, ‘o‘, ‘n‘, ‘g‘, ‘ ‘, ‘c‘,
python动态语言:
In [20]: import sys
In [21]: sys.getrefcount()
增加对象对象的引用次数
1、对象创建
2、将对象添加进容器时,类似list.append()
3、当对象当作参数传递给函数时
减少引用次数
1、应用此对象的变量被显示销毁,del x
2、引用此对象的变量名重新赋值,
3、从容器中移除对象时,类似list.pop()
4、容器本身被销毁
python迭代
迭代:重复做一件事
iterable(可迭代)对象:
1、支持每次返回自己包含的一个成员对象,从头遍历到尾部;
2、可迭代对象实现了__iter__方法
序列类型:如list,str,tuple
非序列类型:如dict,file
用户自定义的一些包含了__iter__()或__getitem__()方法的类
In [23]: l1.__iter__() --- 在内存中创建了一个迭代器的可迭代对象
Out[23]: <listiterator at 0x246d4d0>
迭代器(iterator)又称游标(cursor),它是程序设计的软件设计模式,是一种可以在容器上实现元素遍历的接口;
迭代器是一种特殊的数据结构,在Python中以对象的形式存在;
简单理解:对于一个集体中的每一个元素,想要执行遍历,那么针对这个集体的迭代器定义了遍历集体中每个元素的顺序或者方法;
可迭代对象创建迭代器方法有两种:
In [24]: i1=l1.__iter__()
In [25]: i1.next()
Out[25]: 1
In [26]: i1.next()
Out[26]: 2
In [27]: i2=iter(l1)
In [28]: i2.next()
Out[28]: 1
In [29]: i2.next()
Out[29]: 2
在python中,迭代器是遵循迭代协议的对象
1、使用iter()可从任何序列对象中得到迭代器
2、若要实现迭代器,需要在类中定义next()方法,python3中是__next__()
3、要使得迭代器指向下一个元素,则使用成员函数next()
4、当没有元素时,则引发StopIteration异常
5、for循环可以用于任何可迭代对象
for循环开始时,会通过迭代协议传递给iter()内置函数,从而能够从可迭代对象中获取一个迭代器,返回的对象含有需要的next()方法
根据已有列表生成新列表
for循环
In [31]: l2=[]
In [32]: for i in l1:
....: l2.append(i**2)
....: else:
....: print l2
....:
[1, 4, 9, 16, 25, 36, 49]
列表解析:比for循环快1倍
In [33]: l3=[i**2 for i in l1]
In [34]: print l3
[1, 4, 9, 16, 25, 36, 49]
In [36]: l4=[i**2 for i in l1 if i>=3] (增加if条件处理)
In [37]: print l4
[9, 16, 25, 36, 49]
输出/var/log/目录中以.log结尾的文件
In [39]: os.listdir(‘/var/log/‘)
Out[39]:
[‘spooler‘,
‘sa‘,
‘vmware-caf‘,
‘dmesg.old‘,
‘ntpstats‘,
‘rhsm‘,
‘spice-vdagent.log‘,
‘anaconda.program.log‘,
‘anaconda.yum.log‘,
‘anaconda.ifcfg.log‘,
‘cups‘,
‘btmp‘,
‘vmware-vmsvc.log‘,
‘gdm‘,
‘lastlog‘,
‘vmware-vmusr.log‘,
‘secure‘,
‘tallylog‘,
‘cron‘,
‘samba‘,
‘prelink‘,
‘yum.log‘,
‘vmware-install.log‘,
‘dmesg‘,
‘Xorg.0.log.old‘,
‘maillog‘,
‘messages‘,
‘vmware-tools-upgrader.log‘,
‘ppp‘,
‘anaconda.storage.log‘,
‘wtmp‘,
‘Xorg.0.log‘,
‘audit‘,
‘anaconda.log‘,
‘ConsoleKit‘,
‘anaconda.syslog‘,
‘wpa_supplicant.log‘,
‘httpd‘,
‘boot.log‘,
‘pm-powersave.log‘,
‘dracut.log‘]
In [39]: os.listdir(‘/var/log/‘) --- 目录中文件名为列表
Out[39]:
[‘spooler‘,
‘sa‘,
‘vmware-caf‘,
‘dmesg.old‘,
‘ntpstats‘,
‘rhsm‘,
‘spice-vdagent.log‘,
‘anaconda.program.log‘,
‘anaconda.yum.log‘,
‘anaconda.ifcfg.log‘,
‘cups‘,
‘btmp‘,
‘vmware-vmsvc.log‘,
‘gdm‘,
‘lastlog‘,
‘vmware-vmusr.log‘,
‘secure‘,
‘tallylog‘,
‘cron‘,
‘samba‘,
‘prelink‘,
‘yum.log‘,
‘vmware-install.log‘,
‘dmesg‘,
‘Xorg.0.log.old‘,
‘maillog‘,
‘messages‘,
‘vmware-tools-upgrader.log‘,
‘ppp‘,
‘anaconda.storage.log‘,
‘wtmp‘,
‘Xorg.0.log‘,
‘audit‘,
‘anaconda.log‘,
‘ConsoleKit‘,
‘anaconda.syslog‘,
‘wpa_supplicant.log‘,
‘httpd‘,
‘boot.log‘,
‘pm-powersave.log‘,
‘dracut.log‘]
In [40]:
In [41]: filelist2=[i for i in filelist1 if i.endswith(‘.log‘)]
In [42]: print filelis
filelist1 filelist2
In [42]: print filelist2
[‘spice-vdagent.log‘, ‘anaconda.program.log‘, ‘anaconda.yum.log‘, ‘anaconda.ifcfg.log‘, ‘vmware-vmsvc.log‘, ‘vmware-vmusr.log‘, ‘yum.log‘, ‘vmware-install.log‘, ‘vmware-tools-upgrader.log‘, ‘anaconda.storage.log‘, ‘Xorg.0.log‘, ‘anaconda.log‘, ‘wpa_supplicant.log‘, ‘boot.log‘, ‘pm-powersave.log‘, ‘dracut.log‘]
列表之间交叉相乘
In [43]: l1=[‘x‘,‘y‘,‘z‘]
In [44]: l2=[1,2,3]
In [45]: l3=[(i,j) for i in l1 for j in l2]
In [46]: print l3
[(‘x‘, 1), (‘x‘, 2), (‘x‘, 3), (‘y‘, 1), (‘y‘, 2), (‘y‘, 3), (‘z‘, 1), (‘z‘, 2), (‘z‘, 3)]
In [1]: l1=[‘x‘,‘y‘,‘z‘]
In [2]: l2=[1,2,3]
In [3]: l3=[(i,j) for i in l1 for j in l2 if j != 1] --- 增加if判断
In [4]: print l3
[(‘x‘, 2), (‘x‘, 3), (‘y‘, 2), (‘y‘, 3), (‘z‘, 2), (‘z‘, 3)]
列表一次生成所有数据,占用内存;与range类似,则有生成器,类似xrange;
生成器表达式并不真正创建数字列表,而是返回一个生成器对象,此对象在每一次计算出一个条目后,把这个条目“产生”yield处理
生成器使用惰性计算、或者延迟求值的机制
序列过长,并且每次只需要获取一个元素时,应当考虑使用生成器表达式而不是列表解析器(生成器于Python2.4导入)
>>> [i**2 for i in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> (i**2 for i in range(1,11))
<generator object <genexpr> at 0x0255C288>
>>> g1=(i**2 for i in range(1,11))
>>> g1.next()
1
>>> g1.next()
4
>>> g1.next()
9
>>> g1.next()
16
>>> g1.next()
25
>>> g1.next()
36
>>>
>>> for i in (i**2 for i in range(1,11)):print i/2,
...
0 2 4 8 12 18 24 32 40 50
字典dict
所有的key都是唯一的
字典的深复制和浅复制
dict1=dict
dict2=dict.copy()
copy.deepcopy()
copy.copy()
enumerate产生偏移和元素
range可在非完备遍历中用于生成索引偏移,而偏移处的元素;
如果同时需要偏移索引和偏移元素,则可以使用enumerate()函数;
此内置函数返回一个生成器对象
>>> url="www.baidu.com"
>>> g1=enumerate(url)
>>> g1.next()
(0, ‘w‘)
>>> g1.next()
(1, ‘w‘)
>>> g1.next()
(2, ‘w‘)
>>> g1.next()
(3, ‘.‘)
python文件对象
文件系统是os用于明确磁盘或分区上的文件的方法和数据结构--即在磁盘上组织文件的方法
概括来讲:(变量:具有别名的内存地址)
1、文件是计算机中由OS管理的具有名字的存储区域
2、在Linux系统上,文件被看做是字节序列
文件对象接口
python内置函数open()用于打开文件和创建文件对象;
open(name[,mode[,bufsize]])
open方法可以接收三个参数:name、mode、bufsize
open函数返回一个文件对象
mode指定文件的打开模式;简单模式,r只读,w写入(首部输入),a附加(尾部输入);在模式后使用“+”,表示同时支持输入、输出操作;在模式后附加“b”表示以二进制方式打开
bufsize定义输出缓存;0表示无输出缓存,1表示使用缓存,负数表示使用系统默认设置,正数表示使用近似指定大小的缓冲
>>> dir(file) ---- 文件也是可迭代对象
[‘__class__‘, ‘__delattr__‘, ‘__doc__‘, ‘__enter__‘, ‘__exit__‘, ‘__format__‘, ‘__getattribute__‘, ‘__hash__‘, ‘__init__‘, ‘__iter__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘close‘, ‘closed‘, ‘encoding‘, ‘errors‘, ‘fileno‘, ‘flush‘, ‘isatty‘, ‘mode‘, ‘name‘, ‘newlines‘, ‘next‘, ‘read‘, ‘readinto‘, ‘readline‘, ‘readlines‘, ‘seek‘, ‘softspace‘, ‘tell‘, ‘truncate‘, ‘write‘, ‘writelines‘, ‘xreadlines‘]
>
>>> f1=open(‘c://tftpboot/BF50SW19-B3‘,‘r‘)
>>> type(f1)
<type ‘file‘>
>>> f1.next()
‘feature telnet\n‘
>>> f1.next()
‘feature tacacs+\n‘
>>> f1.next()
‘cfs eth distribute\n‘
>>> f1.close()
>>> f1.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
>>> f1=open(‘c://tftpboot/BF50SW20-B3‘,‘r‘)
>>> f1.fileno() --- 文件描述符
3
>>> f1.readline()
‘BF50SW20-B3(config)# copy ftp: bootflash:\n‘
>>> f1.readlines() --- 返回所有行组成的列表
[‘Enter source filename: n5000-uk9.5.2.1.N1.5.bin\n‘, "Enter vrf (If no input, current vrf ‘default‘ is considered): management\n", ‘Enter hostname for the ftp server: 1.1.1.1\n‘, ‘Enter username: anonymous\n‘, ‘Password: \n‘, ‘***** Transfer of file Completed Successfully *****
>>> f1.tell() --- 返回指针在文件中的位置
37612L
file.seek(offset[,whence]) ---常用于回到文件开头
whence:起点,0从文件头;1从当前位置;2从文件尾部
offset:偏移量
>>> f1.tell()
37612L
>>> f1.seek(0)
>>> f1.tell()
0L
>>> f1.read(10) ---字符串读入所有内容
‘BF50SW20-B‘
>>> f1.tell()
10L
>>> f1.next()
‘3(config)# copy ftp: bootflash:\n‘
>>> f1.tell()
8363L
>>> f1.name
‘c://tftpboot/BF50SW20-B3‘
>>>
>>> f1=open(‘c://tftpboot/BF50SW19-B3‘,‘r+‘)
>>> f1.next()
‘feature telnet\n‘
>>> f1.seek(0,2)
>>> f1.tell()
10709L
>>> f1.write("new line\n")
>>> f1.tell()
10719L
>>> f1.close()
>>> f2=open(‘c://tftpboot/test‘,‘w+‘) ---w/w+, 如果不存在,创建新文件
>>> f2.write(‘hello\n‘)
>>> f2.close()
>>> f3=open(‘c://tftpboot/test‘,‘r‘)
>>> f3.next()
‘hello\n‘
>>> f3.close()
>>> f3=open(‘c://tftpboot/test1‘,‘r‘) --- r/r+, 如果不存在,报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: ‘c://tftpboot/test1‘
>>> f3=open(‘c://tftpboot/test1‘,‘r+‘)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: ‘c://tftpboot/test1‘
>>> f3=open(‘c://tftpboot/test1‘,‘w+‘)
>>> f3.close()
>>> for line in (i**2 for i in range(1,11)):
... f3.write(str(line)+‘\n‘)
... else:
... f3.close()
...
>>> f3.flush()
>>> f3=open(‘c://tftpboot/test1‘,‘r‘)
>>> f3.readlines()
[‘1\n‘, ‘4\n‘, ‘9\n‘, ‘16\n‘, ‘25\n‘, ‘36\n‘, ‘49\n‘, ‘64\n‘, ‘81\n‘, ‘100\n‘]
>>>
f3.xreadlines() --- 迭代器
>>> f4=open(‘c://tftpboot/test2‘,‘w+‘)
>>> import os
>>> l1=os.listdir(‘c://tftpboot‘)
>>> print l1
[‘BF50SW19-B3‘, ‘BF50SW20-B3‘, ‘BF50SW21-B3‘, ‘BF50SW22-B3‘, ‘test‘, ‘test1‘, ‘test2‘]
>>> f4.writelines(l1)
>>> f4.flush()
>>> f4.readlines()
[]
>>> f4.close()
>>> f4.readlines()
>>> l2=[ i+‘\n‘ for i in os.listdir(‘c://tftpboot‘)]
>>> print l2
[‘BF50SW19-B3\n‘, ‘BF50SW20-B3\n‘, ‘BF50SW21-B3\n‘, ‘BF50SW22-B3\n‘, ‘test\n‘, ‘test1\n‘, ‘test2\n‘]
>>> f4=open(‘c://tftpboot/test2‘,‘w+‘)
>>> l2
[‘BF50SW19-B3\n‘, ‘BF50SW20-B3\n‘, ‘BF50SW21-B3\n‘, ‘BF50SW22-B3\n‘, ‘test\n‘, ‘test1\n‘, ‘test2\n‘]
>>> f4.writelines(l2)
>>> f4.seek(0)
>>> f4.readlines()
[‘BF50SW19-B3\n‘, ‘BF50SW20-B3\n‘, ‘BF50SW21-B3\n‘, ‘BF50SW22-B3\n‘, ‘test\n‘, ‘test1\n‘, ‘test2\n‘]
>>> f4.flush()
>>> f4.close()
>>> f4.isatty()
False
>>> f4.tell()
0L
>>> f4.readline()
‘BF50SW19-B3\n‘
>>> f4.tell()
13L
>>> f4.truncate(f4.tell())
>>> f4.seek(0)
>>> f4.readlines()
[‘BF50SW19-B3\n‘]
>>> f4.close()
>>> f4=open(‘c://tftpboot/test2‘,‘w+‘)
>>> f4.encoding
>>> f4.mode
‘w+‘
>>> f4.closed
False
>>> f4.newlines
>>> f4.readline()
‘‘
>>> f4.newlines
>>> f4.softspace
0
>>> f4.close()
>>> f4.closed
True
文件系统功能:os
>>> dir(os)
[‘F_OK‘, ‘O_APPEND‘, ‘O_BINARY‘, ‘O_CREAT‘, ‘O_EXCL‘, ‘O_NOINHERIT‘, ‘O_RANDOM‘, ‘O_RDONLY‘, ‘O_RDWR‘, ‘O_SEQUENTIAL‘, ‘O_SHORT_LIVED‘, ‘O_TEMPORARY‘, ‘O_TEXT‘, ‘O_TRUNC‘, ‘O_WRONLY‘, ‘P_DETACH‘, ‘P_NOWAIT‘, ‘P_NOWAITO‘, ‘P_OVERLAY‘, ‘P_WAIT‘, ‘R_OK‘, ‘SEEK_CUR‘, ‘SEEK_END‘, ‘SEEK_SET‘, ‘TMP_MAX‘, ‘UserDict‘, ‘W_OK‘, ‘X_OK‘, ‘_Environ‘, ‘__all__‘, ‘__builtins__‘, ‘__doc__‘, ‘__file__‘, ‘__name__‘, ‘__package__‘, ‘_copy_reg‘, ‘_execvpe‘, ‘_exists‘, ‘_exit‘, ‘_get_exports_list‘, ‘_make_stat_result‘, ‘_make_statvfs_result‘, ‘_pickle_stat_result‘, ‘_pickle_statvfs_result‘, ‘abort‘, ‘access‘, ‘altsep‘, ‘chdir‘, ‘chmod‘, ‘close‘, ‘closerange‘, ‘curdir‘, ‘defpath‘, ‘devnull‘, ‘dup‘, ‘dup2‘, ‘environ‘, ‘errno‘, ‘error‘, ‘execl‘, ‘execle‘, ‘execlp‘, ‘execlpe‘, ‘execv‘, ‘execve‘, ‘execvp‘, ‘execvpe‘, ‘extsep‘, ‘fdopen‘, ‘fstat‘, ‘fsync‘, ‘getcwd‘, ‘getcwdu‘, ‘getenv‘, ‘getpid‘, ‘isatty‘, ‘kill‘, ‘linesep‘, ‘listdir‘, ‘lseek‘, ‘lstat‘, ‘makedirs‘, ‘mkdir‘, ‘name‘, ‘open‘, ‘pardir‘, ‘path‘, ‘pathsep‘, ‘pipe‘, ‘popen‘, ‘popen2‘, ‘popen3‘, ‘popen4‘, ‘putenv‘, ‘read‘, ‘remove‘, ‘removedirs‘, ‘rename‘, ‘renames‘, ‘rmdir‘, ‘sep‘, ‘spawnl‘, ‘spawnle‘, ‘spawnv‘, ‘spawnve‘, ‘startfile‘, ‘stat‘, ‘stat_float_times‘, ‘stat_result‘, ‘statvfs_result‘, ‘strerror‘, ‘sys‘, ‘system‘, ‘tempnam‘, ‘times‘, ‘tmpfile‘, ‘tmpnam‘, ‘umask‘, ‘unlink‘, ‘unsetenv‘, ‘urandom‘, ‘utime‘, ‘waitpid‘, ‘walk‘, ‘write‘]
目录为文件系统功能;
>>> os.mkdir(‘c://tftpboot/testdir‘)
>>> os.getcwd()
‘C:\\Users\\\xd0\xdc\xe8\xa1‘
>>> os.chdir(‘c://tftpboot‘)
>>> os.getcwd()
‘c:\\tftpboot‘
>>> os.stat(‘test2‘)
nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=0L, st_atime=1490841609L, st_mtime=1490842487L, st_ctime=1490841609L)
>>> os.listdir(os.getcwd())
[‘BF50SW19-B3‘, ‘BF50SW20-B3‘, ‘BF50SW21-B3‘, ‘BF50SW22-B3‘, ‘test‘, ‘test1‘, ‘test2‘, ‘testdir‘]
>>>
>>> os.makedirs(‘a/b/c‘)
>>> os.listdir(os.getcwd())
[‘a‘, ‘BF50SW19-B3‘, ‘BF50SW20-B3‘, ‘BF50SW21-B3‘, ‘BF50SW22-B3‘, ‘test‘, ‘test1‘, ‘test2‘, ‘testdir‘]
>>>
>>> os.removedirs(‘a/b/c‘)
>>> os.listdir(os.getcwd())
[‘BF50SW19-B3‘, ‘BF50SW20-B3‘, ‘BF50SW21-B3‘, ‘BF50SW22-B3‘, ‘test‘, ‘test1‘, ‘test2‘, ‘testdir‘]
>>>
文件相关:
mkfifo()
mknod()
remove()
unlink()
rename()
stat():返回文件状态信息
symlink:创建链接
utime():更新文件时间戳
tmpfile():创建并打开一个新的临时文件
walk():文件目录
>>> os.walk(os.getcwd())
<generator object walk at 0x029F1670>
>>> g1=os.walk(os.getcwd())
>>> g1.next()
(‘c:\\tftpboot‘, [‘testdir‘], [‘BF50SW19-B3‘, ‘BF50SW20-B3‘, ‘BF50SW21-B3‘, ‘BF50SW22-B3‘, ‘test‘, ‘test1‘, ‘test2‘])
>>>
访问权限
>>> os.access(‘test‘,0)
True
>>> os.access(‘test‘,500)
True
>>>
>>> os.chmod(‘test2‘,0640)
os.chown():修改属主、属组
umask():设置默认权限模式
文件描述符
open()
read()
write()
设备文件
mkdev()
major()
minor()
跟文件路径相关
>>> import os.path
>>> dir(os.path)
[‘__all__‘, ‘__builtins__‘, ‘__doc__‘, ‘__file__‘, ‘__name__‘, ‘__package__‘, ‘_abspath_split‘, ‘_getfullpathname‘, ‘abspath‘, ‘altsep‘, ‘basename‘, ‘commonprefix‘, ‘curdir‘, ‘defpath‘, ‘devnull‘, ‘dirname‘, ‘exists‘, ‘expanduser‘, ‘expandvars‘, ‘extsep‘, ‘genericpath‘, ‘getatime‘, ‘getctime‘, ‘getmtime‘, ‘getsize‘, ‘isabs‘, ‘isdir‘, ‘isfile‘, ‘islink‘, ‘ismount‘, ‘join‘, ‘lexists‘, ‘normcase‘, ‘normpath‘, ‘os‘, ‘pardir‘, ‘pathsep‘, ‘realpath‘, ‘relpath‘, ‘sep‘, ‘split‘, ‘splitdrive‘, ‘splitext‘, ‘splitunc‘, ‘stat‘, ‘supports_unicode_filenames‘, ‘sys‘, ‘walk‘, ‘warnings‘]
>>>
basename():路径基名
dirname():父目录名
>>> file1=os.path.basename(‘c:\\tftpboot\\test‘)
>>> dir1=os.path.dirname(‘c:\\tftpboot\\test‘)
>>> file1
‘test‘
>>> dir1
‘c:\\tftpboot‘
>>> os.path.join(dir1,file1)
‘c:\\tftpboot\\test‘
split():返回(dirname()、basename())元组
splitext:返回(filename,extension)元组
getatime()
getctime()
getmtime()
getsize():返回文件的大小
查询:
exists():判断指定文件是否存在
isabs():判断指定路径是否为绝对路径
isdir():是否为目录
isfile():是否为文件
islink():是否符号链接
ismount():是否为挂载点
samefile():两个路径是否指向同一个文件
练习:判断文件是否存在,存在则打开 ;让用户通过键盘反复输入多行数据,追加保存至文件中。
filename=’c:\\tftpboot\\test’
if os.path.isfile(filename):
f1=open(filename,’a+’)
while true:
line=raw_input(‘enter something>’)
if line==’q’ or line==’quit’:
break
f1.write(line+’\n’)
else:
f1.close()
对象的持久存储
pickle
marshal
dbm接口:数据库接口
shevle流式并存入数据库
>>> d1={‘x‘:123,‘y‘:234,‘z‘:345}
>>> f5=open(‘a‘,‘w+‘)
>>> pickle.dump(d1,f5)
>>> f5.readlines()
>>> f6=open(‘a‘)
>>> d2=pickle.load(f6)
>>> print d2
{‘y‘: 234, ‘x‘: 123, ‘z‘: 345}
>>>
函数是python为了代码最大程度的重用和最小化代码冗余而提供的基本程序结构
函数是一种设计工具,它能让程序员将复杂的系统分解为可管理的部件
函数用于将相关功能打包并参数化
在python中可以创建4种函数
1、全局函数,定义在模块种
2、局部函数,嵌套于其他函数种
3、lambda函数,表达式
4、方法,于特定数据类型关联的函数,并且只能与数据类型关联一起使用
python提供了很多内置函数
创建函数def
def是一个可执行语句;因此可以出现在任何能够使用语句的地方,甚至可以嵌套在其他语句种
def创建了一个对象并将其复制给一个变量名(即函数名)
return用于返回结果对象,其为可选;无return语句的函数自动返回none对象;返回多个值时,彼此用逗号分隔,且组合为元组形式返回一个对象
def语句运行之后,可以在程序种通过函数后附加括号进行调用
函数作用域
python创建、改变或者查找变量名都是在名称空间种进行
在代码种变量名被赋值的位置决定了其能被访问到的范围
函数定义了本地作用域,而模块定义了全局作用域
1、每个模块都是一个全局作用域,因此,全局作用域的范围仅限于单个程序文件
2、每次对函数的调用都会创建一个新的本地作用域,赋值的变量除非声明为全局变量,否则均为本地变量
3、所有的变量名都可以归纳为本地、全局或内置的(由__builtin__模块提供)
变量名解析:LEGB规则
本地函数 > 外层函数 > 全局 > 内置
local(function) > enclosing function locals(外层函数) > global(module) > builtin(python)
>>> def f1():
... x=3
... def f2():
... y="hello"
... print x,y
... return f2
...
>>> type(f1)
<type ‘function‘>
>>> f1()()
3 hello
函数参数
>>> def f1(x):
... print x
...
>>> f1(4)
4
>>> f1("abc")
abc
>>> def f2(x,y):
... print x+y
...
>>> f2(3,4)
7
>>> f2("hello ","world")
hello world
>>>
参数传递
>>> m=3;n=4
>>> def f3(x,y):
... x-=1
... print x,y
...
>>> f3(m,n)
2 4
>>> print m,n
3 4
>>>
>>>
>>> def f5(x):
... x.pop()
... print x
...
>>> l1=[1,2,3,4] ----可变对象在函数内部可以修改
>>> f5(l1)
[1, 2, 3]
>>> print l1
[1, 2, 3]
>>> f5(l1[:]) ---- 可变参数副本
[1, 2]
>>> print l1
[1, 2, 3]
参数匹配模型:
默认情况下,参数通过其位置进行传递,从左至右,这意味着,必须精确的传递和函数头部参数一样多的参数
参数传递形式:从左向右,按关键名称匹配,
>>> m=3;n=4
>>> def f3(x,y):
... x-=1
... print x,y
...
>>> f3(m,n)
2 4
>>> f3(y=n,x=m)
2 4
关键字参数:使用“name=value”的语法通过参数名进行匹配
混用时:位置参数放在关键字参数前面
>>> def f5(x,y,z):
... print x,y,z
...
>>> f5(m,n,0)
3 4 0
>>> f5(x=m,y=n,z=0)
3 4 0
>>> f5(m,z=0,y=n)
3 4 0
默认参数:定义函数时使用“name=value”的语法直接给变量一个值,从而传入的值可以少于参数个数;
混用默认值和无默认值的参数时,无默认值参数放前面
In [2]: def f1(x,y,z=9):
...: print x,y,z
...:
In [3]: f1(3,4,4)
3 4 4
In [4]: f1(3,4)
3 4 9
In [6]: def f2(x=1,y,z=9): 有默认参数放在右边
...: print x,y,z
...:
File "<ipython-input-6-6fde60cb511a>", line 1
def f2(x=1,y,z=9):
SyntaxError: non-default argument follows default argument
可变参数:定义函数使用*开头的参数,可用于收集任意多基于位置或关键字的参数
调用函数时使用可变参数要求:
定义函数时使用*:收集位置参数
定义函数时使用**:收集关键字参数
In [7]: def f3(*x):
...: print x
...:
In [8]: f3(3)
(3,)
In [9]: f3(3,4)
(3, 4)
In [10]: f3(3,4,7)
(3, 4, 7)
In [11]: def f4(**x):
....: print x
....:
In [12]: f4(x=1,y=2,z=9)
{‘y‘: 2, ‘x‘: 1, ‘z‘: 9}
In [13]: def f5(x,*y): --- *y收集位置参数
....: print x,y
....:
In [14]: f5(3,4,5)
3 (4, 5)
In [15]: def f6(x,y=10,*z):
....: print x
....: print y
....: print z
....:
In [16]: f6(3,4,5)
3
4
(5,)
In [17]: def f7(*x,**y): --- *x收集位置参数,**y收集关键字参数
....: print x
....: print y
....:
In [18]: f7(3,4,5,i=3,j=6)
(3, 4, 5)
{‘i‘: 3, ‘j‘: 6}
可变参数解包:调用函数,使用*开头的参数,可用于将参数集合打散,从而传递任意多基于位置或关键字的参数
In [19]: l1=[3,4,5]
In [20]: x,y,z=l1
In [21]: print x,y,z
3 4 5
In [22]: def f8(x,y,z):
....: print x,y,z
....:
In [23]: f8(*l1)
3 4 5
In [24]: l2=[‘a‘,‘b‘,‘c‘,‘d‘]
In [25]: f8(*l2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-25-c4c448bb7bdc> in <module>()
----> 1 f8(*l2)
TypeError: f8() takes exactly 3 arguments (4 given)
In [26]: l3=[‘a‘,‘b‘]
In [27]: f8(*l3)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-27-d3a5d34fd4bd> in <module>()
----> 1 f8(*l3)
TypeError: f8() takes exactly 3 arguments (2 given)
In [28]: def f9(x,*y):
....: print x
....: print y
....:
In [29]: f9(3,*l3)
3
(‘a‘, ‘b‘)
In [30]: d1={‘a‘:1,‘b‘:2,‘c‘:3}
In [31]: def f10(x,*y,**z):
....: print x
....: print y
....: print z
....:
In [32]: m=3
In [33]: f10(m,*l3,**d1)
3
(‘a‘, ‘b‘)
{‘a‘: 1, ‘c‘: 3, ‘b‘: 2}
lambda运算符
lambda args: expression
args:以逗号分隔的参数列表
expression:用到args中各参数的表达式
In [34]: lambda x,y: x+y
Out[34]: <function __main__.<lambda>>
In [34]: lambda x,y: x+y
Out[34]: <function __main__.<lambda>>
In [35]: f1=lambda x,y: x+y
In [36]: f1(3,4)
Out[36]: 7
lambda语句定义的代码必须是合法的表达式,不能出现多条件语句(可使用if的三元表达式)和其他非表达式语句,如for和while;
lambda的首要用途是指定短小的回调函数
lambda将返回一个函数而不是将函数赋值给某变量名; 对某个对象做出不同的处理时,把每次处理机制定义为Lambda
In [37]: l3=[(lambda x:x*2),(lambda y:y*3)]
In [38]: for i in l3:
....: print i(4)
....:
8
12
函数式编程
在某个函数中调用其它函数,将函数当作参数使用
也称为泛函编程,是一种编程范式;函数作为参数传递给另一个函数;从而实现在一个函数中调用其他函数;
filter(func,seq):调用一个bool函数来迭代遍历每个seq中的函数;返回一个使func返回值为true的元素序列
map(func,seq1[,seq2…]):将函数作为func作用于给定序列seq中每一个元素,并用一个列表来提供返回值:如果func为None,func表现为一个身份函数,返回一个含有每个序列中元素集合的n个元组的列表
reduce(func,seq[,init]):将二元函数作用于seq序列的元素,每个携带一对(先前的结果以及下一个序列元素),连续的将现有的结果和下一个值作用于获得的随后的结果上,最后减少我们的序列为一个单一的返回值,如果初始值init给定,第一个比较会使Init和第一个序列元素而不是序列的头两个元素
filter(过滤器)
filter()为已知的序列的每个元素调用给定的布尔函数
调用中,返回值为非零值得元素将被添加至一个列表中
In [2]: l1=[1,2,33,23,42,44]
In [3]: def f1(x):
if x>20:return True
...: else:
...: False
...:
In [4]: filter(f1,l1)
Out[4]: [33, 23, 42, 44]
map(映射器)
map()将函数调用“映射”到每个序列的对应元素上,并返回一个含有所有返回值的列表
带有单个队列的map()
In [5]: l1=[0,1,2,3,4,5,6]
In [6]: l2=[‘sun‘,‘mon‘,‘tue‘,‘wed‘,‘thu‘,‘fri‘,‘sat‘]
In [7]: map(f1,l1,l2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-938c23fc23f4> in <module>()
----> 1 map(f1,l1,l2)
TypeError: f1() takes exactly 1 argument (2 given)
In [8]: map(f1,l1)
Out[8]: [None, None, None, None, None, None, None]
In [9]: map(f1,l2)
Out[9]: [True, True, True, True, True, True, True]
In [10]: map(None,l1,l2)
Out[10]:
[(0, ‘sun‘),
(1, ‘mon‘),
(2, ‘tue‘),
(3, ‘wed‘),
(4, ‘thu‘),
(5, ‘fri‘),
(6, ‘sat‘)]
reduce(折叠)
In [15]: def f3(x,y):
....: return x+y
....:
In [16]: l1
Out[16]: [0, 1, 2, 3, 4, 5, 6]
In [17]: reduce(f3,l1)
Out[17]: 21
In [18]: reduce(f3,l1,10)
Out[18]: 31
python闭包,外部函数为内部函数提供环境,内部函数:
外层函数返回后,内层函数仍然可以使用外层函数中的变量(内层函数的环境);
In [19]: def f1(x):
....: def f2(y):
....: return y**x
....: return f2
....:
In [24]: f3=f1(3)
In [25]: f3(2)
Out[25]: 8
In [26]: f3(4)
Out[26]: 64
In [27]: f3=f1(4)
In [28]: f3(3)
Out[28]: 81
In [29]: f3(2)
Out[29]: 16
In [33]: def startPos(m,n):
def newPos(x,y):
print "last P is (%d,%d),and the new P is (%d,%d)" %(m,n,m+x,n+y)
return newPos
....:
In [34]: action=startPos(10,10)
In [35]: action(1,2)
last P is (10,10),and the new P is (11,12)
In [36]: action(-1,3)
last P is (10,10),and the new P is (9,13)
python闭包:定义在外层函数,在内层函数引用的变量;在外层函数直接返回内层函数,作为返回结果;还可以使用外层函数变量,记忆的效果;
闭合作用:调用返回时,内部函数会消失;通过闭合,内层函数记忆了,外层函数中内层函数调用过的变量;
例子:内层函数f2()可以记录外层函数f1()的变量x,外层函数f1()为内存函数f2()提供外部运行环境;
In [4]: def f1(x):
...: def f2(y):
...: return y ** x
...: return f2
...:
In [5]: f2=f1(3)
In [6]: f2(2)
Out[6]: 8
In [7]: f2(3)
Out[7]: 27
In [8]: f2(4)
Out[8]: 64
棋盘,棋子行走;外部函数定义当前位置,内层函数计算行走路径;
In [9]: def startPos(m,n):
...: def newPos(x,y):
...: print "the old position is (%d,%d), and the new position is (%d,%d)." % (m,n,m+x,n+y)
...: return newPos
...:
In [10]: action=startPos(10,10)
In [11]: action(1,2)
the old position is (10,10), and the new position is (11,12).
In [12]: action(-1,3)
the old position is (10,10), and the new position is (9,13).
装饰器(闭包的进一步应用)
1、装饰器自身是一个函数,用于装饰其他函数;实现函数功能在不同环境中适用,代码重用;
常用于切面需求的场景,插入日志、性能测试、事务处理等;可以抽离大量函数无关的功能,
2、功能及作用:增强被装饰函数的功能;
3、接收一个函数对象作为参数,以对其进行增强;
In [14]: def deco(func):
def wrapper():
print "please say something:"
func()
print "no zuo no die"
return wrapper
....:
In [16]: @deco
def show():
print "i am form Mars"
....:
In [17]: show()
please say something:
i am form Mars
no zuo no die
In [18]:
带参数的装饰器
内层函数接收外层函数的参数,并且传递给被装饰函数,被调用时传递参数
In [18]: def deco(func):
....: def wrapper(x):
....: print "please say something"
....: func(x)
....: print "no zuo no die"
....: return wrapper
....:
In [20]: @deco
....: def show(x):
....: print x
....:
In [21]: show("hello mars")
please say something
hello mars
no zuo no die
函数的设计规范:
耦合性:
1、通过参数接收输入,以及通过return产生输出以保证函数的独立性
2、尽量减少使用全局变量进行函数间通信
3、不要再函数中修改可变类型的参数
4、避免直接改变定义在另外一个模块中的变量
聚合性:
1、每个函数都应该有一个单一、统一的目标
2、每个函数的功能都应该相对简单
复用性,
可扩展性,不需要修改以前的程序;
可读性,容易理解,没有注释也能易懂;函数名易懂
面向对象编程
程序=指令+数据
代码可以选择以指定为核心或以数据为核心进行编写
两种类型:
1、以指令为中心:围绕“正在发生”进行编写
面向过程编程:程序具有一系列线性步骤:主体思想是代码作用于数据
2、以数据为核心:围绕“将影响谁”进行编写
面向对象编程(oop):围绕数据及为数据严格定义的接口来组织程序,用数据控制对代码的访问
面向对象的核心概念
所有编程语言的目的都是提供一种抽象方法
在机器模型(“解空间”)与实际解决的问题模型(”问题空间“)之间,程序员必须建立一种联系
面向过程:程序=算法+数据结构
面向对象:将问题空间中的元素以及他们在解空间中的表示物抽象为对象,并允许通过问题来描述问题而不是方案;可以把对象想象成一种新型变量,它保存着数据,但可以对自身的数据执行操作
类型由状态集合(数据)和转换这些状态的操作集合组成
类抽象:
类:定义了被多个同一类型对象共享的结构和行为(数据和代码)
类的数据和代码:即类的成员
数据:成员变量或实例变量
成员方法:简称为方法,是操作数据的代码,用于定义如何使用成员变量;因此一个类的行为和接口是通过方法来定义的
方法和变量:
私有:内部使用
公共:外部可见
面向对象的程序设计方法
1、所有东西都是对象
2、程序是一大堆对象的组合
通过消息传递,各对象知道自己该做什么
消息:即调用请求,它调用的是从属于目标对象的一个方法
3、每个对象都有自己的存储空间,并可容纳其他对象
通过封装现有对象,可以制作成新型对象
4、每个对象都属于一种类型
类型:即类
对象是类的实例
类的一个重要特性为”能发什么样的消息给它“
5、同一个类的所有对象都能接收相同的消息
对象的接口
1、定义一个类后,可以根据需要实例化出多个对象
2、如何利用对象完成真正有用的工作?
首先,必须有一种方法能向对象发送请求,令其做一些事情
其次,每个对象仅能接收特定的请求
能向对象发送的请求由其”接口“进行定义
对象的”类型“或”类“则规定了它的接口形式
例如:类型名:light
接口:on(),off(),brighten(),dim()
类:将同一种具体物事的共同特性抽象出来的表现;
状态和转换状态的操作;状态为数据,转换操作为方法;
类间的关系
依赖:(use-a)
一个类的方法操纵另一个类的对象
聚合(has-a)
类A的对象包含类B的对象
继承(is-a)
描述特殊与一般的关系
面向对象编程的原则:封装、继承及多态
封装的作用
1、隐藏实现方案细节
2、将代码及其处理的数据绑定在一起的一种编程机制,用于保证程序和数据不受外部干扰且不会被误用
继承的作用
1、一个对象获得另一个对象属性的过程;用于实现按层分类的概念
2、一个深度继承的子类继承了类层次中它的每个祖先的所有属性
3、超类、基类、父类
4、子类、派生类
多态的作用
1、允许一个接口被多个通用的类动作使用的特殊,具体使用哪个动作与应用场合相关
2、“一个接口,多个方法”
用于为一组相关的动作设计一个通用的接口,以降低程序复杂性
python类和实例
类是一种数据结构,可用于创建实例
一般情况下,类封装了数据和可用于该数据的方法
python类是一个可调用对象,即类对象,()调用方法
python2.2之后,类是一种自定义类型,而实例则是声明某个自定义类型的变量
实例初始化
通过调用类来创建实例(instance=ClassName(args…))
类在实例化时可以使用__init__和__del__两个特殊的方法
python中创建类
python使用关键字class关键字创建类,语法格式如下:
1、class ClassName(bases):
class documentation string
class suite
2、超类是一个或多个用于继承的父类的集合
3、类体可以包含:声明语句、类成员定义、数据属性、方法
注意:
如果不存在继承关系,ClassName后面的bases可以不提供
类文档可选
Class语句的一般形式(驼峰命名方式)
class ClassName(bases):
date=value --- 数据属性,类属性
def method(self,…): --- 方法属性,self对自身实例实施操作
self.member=value --- 实例属性
In [1]: class TestClass():
...: pass
...:
In [2]: type(TestClass)
Out[2]: classobj
In [3]: obj1=TestClass()
In [4]: type(obj
obj1 object
In [4]: type(obj1)
Out[4]: instance
python中,class语句类似def,是可执行代码;直到运行class语句后类才会存在
In [5]: class FirstClass: --- 类名
...: spam=30 --- 类数据属性
...: def display(self): --- 类方法,属于可调用的属性
...: print self.spam
...:
In [6]: x=FirstClass() --- 创建类实例
In [7]: x.display() --- 方法调用
30
class语句内,任何赋值语句都会创建类属性;
每个实例对象都会继承类的属性并获得自己的名称空间
python类方法及调用
1、实例(对象)通常包含属性
可调用的属性:方法,object.method()
数据属性
2、在opp中,实例就像是带有“数据”的记录,而类是处理这些记录的“程序”
a.通过实例调用方法相当于调用所属类的方法来处理当前实例
b.类似instance.method(args…)会被自动转换为class.method(instance,args…),如前面的例子,x.display()会被自动转换为FirstClass.display(x),即调用类的方法来处理实例x
c.因此,类中每个方法必须具有self参数
d.在方法内对self属性做赋值运算会产生每个实例自己的属性
e.python规定,没有实例,方法不允许被调用,此即为“绑定”
In [8]: class ThirdClass():
...: data="hello ThirdClass"
...: def setdata(self,x):
...: self.str=x
...: def printdata(self):
...: print self.str
...:
In [9]: ins1=ThirdClass()
In [10]: ins1.data
Out[10]: ‘hello ThirdClass‘
In [11]: ins1.setdata("cxiong")
In [12]: ins1.printdata()
cxiong
python类和实例的属性
1、class语句中的赋值语句会创建类属性,如前面例子中的spam
2、在类方法中对传给方法的特殊参数self进行赋值会创建实例属性
In [13]: class MyClass():
....: gender=‘Male‘ ---- 类属性
....: def setName(self,who):
....: self.name=who ---- 实例属性,实例化后调用执行
....:
In [14]: x=MyClass()
In [15]: y=MyClass()
In [16]: x.gender --- 通过爬树搜索,gender属性会从MyClass类中获取到
Out[16]: ‘Male‘
In [17]: x.name --- 在setName方法调用之前,MyClass类不会把name属性附加到实例x上,当然也可以重装__init__创建构造器直接为实例提供
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-17-ebfcbb65f7c8> in <module>()
----> 1 x.name
AttributeError: MyClass instance has no attribute ‘name‘
In [18]: x.setName(‘tom‘)
In [19]: x.name
Out[19]: ‘tom‘
In [20]: y.setName(‘jerry‘)
In [21]: y.gender,y.name
Out[21]: (‘Male‘, ‘jerry‘)
In [22]: x.gender,x.name
Out[22]: (‘Male‘, ‘tom‘)
python构造器
创建实例时,python会自动调用类中的__init__方法,以隐形地为实例提供属性
1、__init__方法被称为构造器
2、如果类中没有定义__init__方法,实例创建之初仅是一个简单的名称空间
__varname__():python解释器自动调用
In [33]: class MyClass():
....: data="hello MyClass"
....: def __init__(self,who):
....: self.name=who
....:
In [34]: x=MyClass("tom")
In [35]: y=MyClass("jerry")
In [36]: x.data
Out[36]: ‘hello MyClass‘
In [37]: x.name
Out[37]: ‘tom‘
In [38]: y.data
Out[38]: ‘hello MyClass‘
In [39]: y.name
Out[39]: ‘jerry‘
In [40]: class Animal:
....: name="someone" --- 数据属性(成员变量)
....: def __init__(self,voice=‘hi‘): --- 重载构造函数,默认值=hi
....: self.voice=voice
....: def __del__(self): --- 重装析构函数
....: pass --- 省略
....: def saySomething(self): ---方法属性(成员函数)
....: print self.voice
....:
In [41]: tom=Animal() ----创建实例
In [42]: tom.saySomething() --- 调用实例方法
hi
In [43]: jerry=Animal(‘hello!‘)
In [44]: jerry.saySomething() --- 调用实例方法
hello!
类的特殊属性
可以使用类的__dict__字典或python内置的dir()函数来获取类的属性,可用类的属性和方法
In [47]: dir(MyClass)
Out[47]: [‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘data‘]
In [48]: MyClass.__dict__
Out[48]:
{‘__doc__‘: None,
‘__init__‘: <function __main__.__init__>,
‘__module__‘: ‘__main__‘,
‘data‘: ‘hello MyClass‘}
实例属性
实例仅拥有数据属性(严格意义上来说,方法是类属性)
1、通常通过构造器__init__为实例提供属性
2、这些数据属性独立于其他实例或类
3、实例释放时,其属性也将被清除
内建函数dir()或实例的特殊属性__dict__可用于查看实例属性
In [49]: dir(x)
Out[49]: [‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘data‘, ‘name‘]
In [50]: x.__dict__
Out[50]: {‘name‘: ‘tom‘}
实例的特殊属性
方法的可用变量
1、实例变量:指定变量名称及实例自身进行引用,self.变量名
2、局部变量:方法内部创建的变量,可直接使用
3、类变量(静态变量):通过指定变量名与类名进行引用,类名.变量名
4、全局变量:直接使用
In [51]: class c():
....: d1="hell c class"
....: def __init__(self,x):
....: self.insdata=x
....:
In [52]: i1=c(50)
In [53]: i2=c(100)
In [54]: i1.d1
Out[54]: ‘hell c class‘
In [55]: i2.d1
Out[55]: ‘hell c class‘
In [56]: i1.d1="new value"
In [57]: i1.d1
Out[57]: ‘new value‘
In [58]: i2.d1
Out[58]: ‘hell c class‘
In [59]: c.d1
Out[59]: ‘hell c class‘
In [60]: c.d1="class new value" ---静态变量修改 影响所有实例
In [61]: i1.d1
Out[61]: ‘new value‘
In [62]: i2.d1
Out[62]: ‘class new value‘
继承
继承描述了基类的属性如何”遗传“给派生类
1、子类可以继承它的基类的任何属性,包括数据属性和方法
2、一个未指定基类的类,其默认有一个名为object的基类
3、python允许多重继承
创建子类
1、创建子类时,只需在类名后跟一个或从其中派生的父类
2、clas SubClassName(ParentClass1[,ParentClass2,…])
optional class documentation string
class_suite
In [63]: class ParentClass(object):
....: ‘parent class‘
....: gender=‘male‘
....: def setName(self,who):
....: self.name=who
....:
In [64]: class ChildClass(ParentClass):
....: ‘child class‘
....: def displayInfo(self):
....: print self.gender,self.name
....:
In [65]: x=ChildClass()
In [66]: x.setName(‘tom‘)
In [67]: x.displayInfo()
male tom
In [68]: dir(ParentClass)
Out[68]:
[‘__class__‘,
‘__delattr__‘,
‘__dict__‘,
‘__doc__‘,
‘__format__‘,
‘__getattribute__‘,
‘__hash__‘,
‘__init__‘,
‘__module__‘,
‘__new__‘,
‘__reduce__‘,
‘__reduce_ex__‘,
‘__repr__‘,
‘__setattr__‘,
‘__sizeof__‘,
‘__str__‘,
‘__subclasshook__‘,
‘__weakref__‘,
‘gender‘,
‘setName‘]
In [69]: dir(ChildClass)
Out[69]:
[‘__class__‘,
‘__delattr__‘,
‘__dict__‘,
‘__doc__‘,
‘__format__‘,
‘__getattribute__‘,
‘__hash__‘,
‘__init__‘,
‘__module__‘,
‘__new__‘,
‘__reduce__‘,
‘__reduce_ex__‘,
‘__repr__‘,
‘__setattr__‘,
‘__sizeof__‘,
‘__str__‘,
‘__subclasshook__‘,
‘__weakref__‘,
‘displayInfo‘,
‘gender‘,
‘setName‘]
In [70]:
python中几乎所有属性的获取都可以使用object.attribute的格式;
不过,此表达式会在Python中启动搜索一一搜索连续的树
class语句会产生一个类对象,对class的调用会创建实例,实例自动连接至创建此实例的一个或多个类
类连接至其超类的方式
将超类在类头部的括号内,其从左向右的顺序会决定树中的次序
由下至上,由左至右
图中所有的对象都是名称空间,而继承就是由下而上搜索此树来寻找属性名称所出现的最低的位置
继承方法专用化
继承会先在子类寻找变量名,然后才查找超类,因此,子类可以对超类的属性重新定义来取代继承而来的行为
1、子类可以完全取代从超类继承而来的属性
2、也可以通过已覆盖的方法回掉超类来扩展超类的方法
In [70]: class ParClass(object):
....: def setInfo(self,sex=‘male‘):
....: self.gender=sex
....:
In [71]: class ChiClass(ParClass):
....: def setInfo(self,who): ---- 覆盖父类的setInfo方法
....: self.name=who
....:
In [72]: x=ChiClass()
In [73]: x.setInfo("tom")
In [74]: x.name
Out[74]: ‘tom‘
In [75]: x.gender
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-75-dcfdb2ec694c> in <module>()
----> 1 x.gender
AttributeError: ‘ChiClass‘ object has no attribute ‘gender‘
In [76]: class ChiClass(ParClass):
def setInfo(self,who):
self.name=who
....: ParClass.setInfo(self) --- 回调用父类的方法
....:
In [77]: x=ChiClass()
In [78]: x.setInfo("tom")
In [79]: x.name
Out[79]: ‘tom‘
In [80]: x.gender
Out[80]: ‘male‘
issubclass()
布尔函数,判断一个类是否由另一个类派生,语法:issubclass(sub,sup)
isinstance()
布尔函数,判断一个对象是否是给定类的实例,语法isinstance(obj1,class_obj2)
hasattr()
布尔函数,判断一个对象是否拥有指定的属性,语法hasattr(obj,attr)
类似还有getattr(),setattr()和delattr()
super()
在子类中找出其父类以便于调用其属性
一般情况下仅能采用非绑定方式调用祖先类方法
而super()可用于传入实例或类型对象,语法super(type[,obj])
运算符重载
运算符重载是指在方法中拦截内置的操作--当类的实例出现在内置操作中,python会自动调用自定义的方法,并且返回自定义方法的操作结果
1、运算符重载让类拦截常规Python运算
类可重载所有Python表达式运算符
类也可重载打印、函数调用、属性点号运算等内置运算
2、重载使类实例的行为像内置类型
3、重载通过提供特殊名称的类方法实现
运算符重载并非必需,并且通常也不是默认的
可调用对象
函数
内置函数
自定义函数 def lambda
函数操作,()运算符
类
类方法
函数的属性:
__doc__
__name__
__dict__
__code__
__globals__
方法的属性:
__doc__
__name__
__class__:方法所属的类
__func__:实现该方法的函数对象
__self__:调用此方法的实例
内置函数:
__doc__
__name__
__self__
类:
__doc__
__name__
__bases__
__dict__
__module__:定义了当前类的模块名称
实例:
__class__
__dict__
以上是关于python基础语法的主要内容,如果未能解决你的问题,请参考以下文章