2014年9月,新疆乌鲁木齐,在51CTO学院看着alex老师的python教学视频,不得不说这是我第一次接触python这门高级语言,从最开始的一无所知到现在能够用python写脚本,再到未来10个月内能够用python开发项目,这一步一步成长,充满着坎坷,汗水。在2014年9月--2015年12月,用python写的脚本帮助我做了很多事情,其中自己感觉最有用的就是自己写的一个批量管理服务器的脚本,我在公司管理着100多台服务器,没有一个运维平台的,都是手动挨个挨个管理,实在费劲,而且那时候对puppet,saltstack这些管理工具也不熟悉,所以只能自己写批量管理工具了,这是第一个我觉得在工作上能够解放双手,能够大幅提高工作效率的脚本,这个脚本在改良以后能够适用于一些采集信息的需求......总之,be prond of python!!
言归正传,学习python就要知道什么是python,python能干嘛,python的哪个版本是主流,python的知识点有哪些and so on!
本章主要介绍什么python,语言的分类,数据类型,python的基本操作(字典,列表,字符串,数字,元组,运算符之类的)
什么是python?
Python(英语发音:/ˈpaɪθən/), 是一种面向对象、解释型计算机程序设计语言,由龟叔(Guido van Rossum)于1989年发明,第一个公开发行版发行于1991年。
那么说的深点,我们从编程语言的角度去看python:
编译型和解释型:
编译型语言:
程序在执行之前需要一个专门的编译过程,把程序编译成 为机器语言的文件,运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依赖编译器,跨平台性差些。
如C、C++、 Delphi等.
解释型语言:
编写的程序不进行预先编译,以文本方式存储程序代码。在发布程序时,看起来省了道编译工序。但是,在运行程序的时候,解释性语言必须先解释再运行。
如 shell,BASIC
动态语言和静态语言:.
动态语言:
意思就是数据类型的检查是在程序运行时做的,如ruby、python........。
静态语言:
数据类型的判断是在程序运行前判断,在写程序之前就要申明所有的数据类型,比如C#、java。
强类型定义语言和弱类型定义语言:
强类型定义语言:
强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。java、.NET、C++、python等都是强制类型定义的。
也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。
弱类型定义语言:
与强类型定义语言相反,数据类型可以被忽略的语言。
从以上三点可得,python是一门动态解释性的强类型定义语言。
python能干嘛?
我们搞明白了python语言的特性(或者说什么是python),那么我们就要知道python能够干嘛了。
1、图形界面:比如PyQt,WxPython,Tkinter等等都能够编写GUI用户界面
2、网络编程,包括web网站,服务器后台衔接等,优秀web框架Django、flask等
3、系统管理工具: 比如saltstack,Ansible等
4、科学计算:Numpy、SciPy等
5、人工智能、游戏、机器人等
Python的优缺点
从python的基因来看,我们就能看出python的优缺点了,
优点:
1 语言简洁,直观。
2 开发效率高,第三方的库非常多
3 可移植性,跨平台能力强,经过修改后就可以从linux迁移到windows。
4 可嵌入型,你可以把 Python 嵌入你的 C/C++程序,从而向你的程序用户提供脚本功能。
缺点:
1 运行速度慢,这个速度慢不是人类能够通过肉眼或者感觉感知的,这个是相对的慢,python相对于C,JAVA来说是慢一拍,毕竟是解释型语言。说到这里我想有人会问,为啥同样跑在虚拟机之上的java会比python快呢?好吧,据我说知,python首先是因为GIL,第二呢我个人感觉是垃圾回收机制,python的垃圾回收机制特别简单,一个对象有2个标准头信息,1 类型,2 引用次数类型是说这个变量属于什么类型的变量,第二个呢说明这个变量是否有人引用,引用一次的话引用次数+1,如果没有人引用那么为0,那么启用垃圾回收机制来回收。而java的垃圾回收机制没那么简单,算法也特多,什么跟踪收集器,增量收集器呀and so on!(有兴趣的同学可以自行研究,本人略懂一二),所以在此之上java的速度会比python快相对来说。
2 代码不能够完全加密,源码以明文形式存放,如果考虑到代码不泄密的话,那么请使用其他语言.
3 多线程不能够充分利用多CPU的问题,这个受制于GIL(Global Interpreter Lock)。
python版本问题
目前主流的是python2.7 和 python 3.x,对于我们来说该如何选择?我们先浏览下官网的说法吧:https://docs.python.org/3/whatsnew/2.7.html
从官网来看,官方建议我们尽快升级到3.X版本,Python 2.7目前会保持支持的核心开发团队(接收安全更新和其他bug修复)至少在2020年之前。
那么python3.X和python2.X有什么区别呢,我个人觉得python3相对于python2来说是做了化繁从简的工作。好吧,简单罗列下面几点:
| python 2.x | python 3.x |
| print "xxxx" | print("xxxxxxx") |
| 1/2 = 0 | 1/2=0.5 |
| Unicode字符串和非Unicode字符串 | Unicode编码,支持中文 |
| 字典有has_key | 字典没有has_key |
| 有input/raw_input | 只有input |
数据类型:
1 整形
任意大小的整数。
2 浮点型
也就是小数,如1.2 ,3.4等,但是对于很大或很小的浮点数,就必须用科学计数法表示,把 10用 e 替代,1.23x109就是 1.23e9 ,或者 12.3e8 ,
0.000012 可以写成 1.2e-5。并且浮点数计算的话会存在精度差。
3 字符串
任意的单引号或者双引号括起来的内容。
4 布尔型
True or False。
5 空值
空值是 Python 里一个特殊的值,用 None 表示。 None 不能理解为 0 ,因为 0 是有意义的,而 None 是一个特殊的空值。
6 字典
一种由{}引用起来的键值对,形式如这样{key:value},如{'name':'温柔易淡'},value可更改,可迭代。
7 元组
一种由()引用起来的元素,里面的元素不可更改,可迭代。
8 列表
一种由[]引用起来的元素,里面的元素可更改,可迭代。
9 集合
一个无序不重复元素集,我在之前学过的其他的语言好像没有见过这个类型,基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算,和我们初中数学学的集合的非常的相似
运算符
1 加减乘除(+-*/)
2 = 赋值号,把右边的对象和左边的变量进行关联引用。
3 += 比如a+=1 就等于a+1=a ,还有-=、*=之类的。
4 & 与运算,这个二进制位必须在 2 组数中都为真,结果才返回真。
5 | 或运算,这个二进制位只需在其中一组数据中为真即返回真。
6 ^ 异或运算,只要这个二进制位在两组数据中不相同就返回真。
7 <<左移运算,在二进制位下把数值整体往左移动若干位。
8 >>右移运算,在二进制位下把数值整体往右移动若干位。
9 逻辑运算符, and 、or、not
10 关系运算 in 、not in
11 验证引用关系运算 is 、not is
缩进和注释
1 Python 是强制缩进的语言,它通过缩进来确定一个新的逻辑层次的开始和结束,这也是python 语言的最重要的特色之一
2 同一逻辑层次级别的代码缩进必须保持一致
3 顶层逻辑级别的代码必须不能有缩进(新行的开始不能有空格)
4 整个程序的缩进风格应保持一致, 一般为 4 个空格或 2 个空格, 官方的推荐是用 4 个空格,当然用 tab 键也可以,但是在 Windows 上的 tab 键和 Linux 上的不一致,会导致你在
Windows 上开发的程序 copy 到 Linux 上后运行出错,所以还是建议用 4 个空格。
5 有关注释:
当你写的代码逻辑变的复杂的时候,一定不要忘记给你的代码加上注释,否则过不了几天,你再返回头来看自己的代码的时候,很有可能你都不知道自己写了些什么,更别提
别人能看懂你的代码了, 保证你的代码简洁、 易读是一个专业程序员最基本的道德品质,那给你的代码加多少的注释算是合适呢?一般情况下,源程序有效注释量应该在 20%以
上,注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。
just practice it!
说了那么多,我们应该对python有个认识了吧。那么就该动手操作他了,好了,那些怎么安装python解释器 的步骤我就不赘述了,还有解释器的,我们就用默认的就可以了。
官方版本的解释器:CPython。这个解释器是用 C 语言开发的,所以叫 CPython。
1 hellow world:
>>> print("hello world") #print() 是打印输出的一个函数
hello world
2 变量的使用:
什么是变量?
简单的来说就是变化的量(数据在程序运行中可能变化或被赋值,这称为变量),说白了变量就是数据在内存空间存储的表示。
如何使用变量?
>>> name='温柔易淡'
变量被赋值的过程:
1 创建一个对象,数值为'温柔易淡'
2 创建一个变量name
3 把变量和对象进行一个关联。
注意:
1 变量到对象连接的关系叫做引用,在内存中以指针形式实现。
2 对象的复用,对相同对象值的赋值将被复用,除非拷贝与深拷贝。
3 对象两个标准头信息:
类型标志:标志此变量值的类型
引用计数器: 计数器对变量引用来计数, 如果都没有被引用则为 0,并在一段时间没有引用后启用回收机制。
4 查看引用次数
Import sys
Sys.getrefcount(1)
>>> name=input("input your name ==>")
input your name ==>温柔易淡
>>> print(name) #这里是print的内容是引用这个name的变量,应用变量直接写变量名就行了,不像shell一样需要在变量名之前添加$号
温柔易淡
说说每一步执行的过程吧
1 input这个函数把()里面的内容打印出来后等待用户输入,把输入的数据以源数据类型赋值给变量name
2 打印信息,等待用户输入
3 print函数把name这个变量的值给打印出来
3 字符串的操作
什么是字符串刚才我也已经介绍了,那么下面我们动手来操作字符串。
首先说第一个问题? ==>>> 字符串的+号是怎么一回事的?
在我的理解,C语言是没有专门的字符串变量的,那它有两种方式来处理字符串的存储和运算,1 字符数组,2 字符指针:
字符数组例子如下:
void main(void) { static char string [ ] = "test!"; #定义一个字符数组,数组名为string,它代表符数组的首地址。 printf("%s\n",string); #打印这个字符数组。 }
字符指针的我就不多说了,因为我也不会写C。
C语言对字符串常量是按字符数组处理的,实际上在内存开辟了一个字符数组用来存放字符串数组,比如我们上面的例子,其实数组内容就是['t','e','s','t','!'],它在内存的地址就是连续的一段,那么在程序运行期间该数组内存地址之后的内存地址肯定是被其他的给占用了。此时当我们用python在对字符串做+号运算时(实际上是调用了C的代码),因为在字符数组后面没有可用的内存空间了,所以只能在内存新开辟一段内存来存放['t','e','s','t','!']和加进来的数组。举个例子理解下,比如我们要在字符串test+hello,那么实际上是在内存新开辟一段空间来存放test+hello的内容的,因为数组['t','e','s','t','!']之后是没有可用的内存空间了,所以只能是用新开辟的空间来存放['t','e','s','t','!','h','e','l','l','o']。所以我们可以总结出来,我们在print()的时候,如果里面用+来拼接字符串的话,那么内存占用的开销比较大,所以我们一般建议使用格式化输出%s/%d或者fromat。
首先看看字符串有哪些方法:
>>> b='abc' >>> dir(b) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] 那么我们就在这里列举一些常用的方法吧 我们在看源码的时候会发现str定义的一些方法里面写的内容都是出来注释之外都是pass,因为它调用的都是C的代码。 >>> a='hellow world,i come from jiangxi province and work in Beijing' #将一句话赋值为一个变量a >>> a 'hellow world,i come from jiangxi province and work in Beijing' >>> a[1:10] 'ellow wor' #切片处理,把变量a的下标为1到10的这段字符串打印出来,整数表示是从头开始,第一个数字1表示从下标1的字符开始,第二个10表示到下标为10的结束,这里下标你可以理解为索引。 >>> a[1:30:2] 'elwwrdicm rmjag' #也是切片处理,注意看[]里面这里多个2,这个2的意思是步进为2,意思是说把变量a的下标从1到10,每隔2个取出来。 >>> a.count('h') #统计变量a里面有多少个h这个字符 。 1 >>> a.count('o') #同上,统计多少个o。 6>>> a.swapcase() #把变量a里面的字符串做大小写转换。 'HELLOW WORLD,I COME FROM JIANGXI PROVINCE AND WORK IN bEIJING' >>> a[-30:-4] # 把变量a里面下标为-30到-4的内容打印出来,这里负数的话表示从结尾开始。 'i province and work in Bei' >>> a[-30:-4:3] 'irienwkne' 也是切片处理,注意看[]里面这里多个3,这个3的意思是步进为3,意思是说把变量a的下标从-30到-4,每隔3个取出来。 >>> a="hellow" >>> b="world" >>> a+b 'hellowworld' >>> a+" "+b #拼接字符串,可以直接用+来拼接 'hellow world' >>> b='abc' >>> b.__add__('asdf') #相当于做了个加法,实际等于b+'asdf' 'abcasdf' >>> b.__contains__('a') #判断字符a是否在b里面 True >>> b.__hash__() #计算b的哈希值,这个一般用的少 4782722299428341007 >>> c='ABCabc' >>> c.casefold() #转换大小写 'abcabc' >>> b.center(100,'*') #格式化输出,一般咱们传参2个参数就行,第一个是输出多少个,第二个是输出什么内容,默认为空, '************************************************abc*************************************************' >>> c="ABCabc" >>> c 'ABCabc' >>> c.encode('gbk') #指定gbk编码方式 b'ABCabc' >>> c.endswith('bc') #匹配指定字符串结尾的 True >>> c.startswith('bc') # 匹配指定字符串开头的 False >>> c.startswith('Ab') False >>> c.expandtabs() #把tab健转为空格 'ABCabc' >>> c='tab\tABC' >>> c.expandtabs() #把字符串的制表符给去除 'tab ABC' >>> c.expandtabs(tabsize=1) #把字符串的制表符给去除,指定制表符大小。 'tab ABC' >>> c.expandtabs(tabsize=0) 'tabABC' >>> c.__len__() #测量字符串的长度,相当于调用了len方法 7 >>> c.find('a') #查找字符串,如果找到了就返回字符所在的序号,如果没有找到就返回-1 1 >>> c.find('P') -1 >>> c="hellow {0},your come from {1}" #这里定义2个传入参数的地方 >>> c.format('ljf','jx') #字符串格式化输出,我们在上面定义了多少个传入的参数,那么就在这里传入多少个参数。 'hellow ljf,your come from jx' >>> c="ABCabc" >>> c.capitalize() #字符串的首字母大写 'Abcabc' >>> c.casefold() #字符串转换为小写。 'abcabc' >>> a.index('b') #查找指定字符的索引 4 >>> a.isalnum() #如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False True >>> a.isalpha() #如果变量a里面至少有一个字符串并且所有字符都是字母,那么就是True,否则就是False。 False >>> aa='ABCabc' >>> aa.islower() #如果字符串都是小写,那么返回的就是True,否则就是False False >>> ad='adce' >>> ad.islower() True >>> ac=' ' >>> ac.isspace() #如果变量ac是空格或者为空,那么就是True。 True >>> aa.isspace() False >>> aa.istitle() #如果aa这个变量里面所有单词字符串开头大写,那么就返回True,否则返回Flase False >>> ab='This World' >>> ab.istitle() True >>> aa.isupper() #判断是否都是大写 False >>> aa 'ABCabc' >>> '?'.join(aa) #把变量a里面的内容都用?来拼接起来, 'A?B?C?a?b?c' >>> aa.ljust(20,'B') # 字符串左对齐,输入的第一个参数是宽度,第二个参数是用什么填充。 'ABCabcBBBBBBBBBBBBBB' >>> aa.lower() #全部转换为小写。 'abcabc' >>> aa 'ABCabc' >>> ae=" sdfl" >>> ae.lstrip() #去除字符串左边的空格,当然也可以传参其他的字符进去 'sdfl' >>> af="nihao123helloworld" >>> af.partition('123') #partition方法相就是指定一个字符分隔符,把这个字符的前后以及字符本身进行三分。 ('nihao', '123', 'helloworld') 以下罗列的是与咱们常用的几个左函数与之对应,下面五个是从右边开始的,使用方法都是一样的,但是就是。 'rfind' 'rindex' 'rjust' 'rpartition' 'rsplit' 'rstrip >>> ag=""" ... hwloadf ... asdcxv123 ... asdf456 ... """ >>> ag.splitlines() #以换行符作为分隔符来切割字符串 ['', 'hwloadf', 'asdcxv123', 'asdf456'] >>> ag.swapcase() #大小写转换 '\nHWLOADF\nASDCXV123\nASDF456\n' >>> ag.title() #把str的单词首字母大写。 '\nHwloadf\nAsdcxv123\nAsdf456\n' >>> ad 'adce' >>> ad.swapcase() 'ADCE' >>> ad.upper() #将str转换为大写。 'ADCE' >>> ad 'adce' >>> ad.zfill(21) #将字符串左边用0进行填充,传入的参数就是填充的宽度。 '00000000000000000adce'