一种面向对象,面向函数的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议[2]. Python语法简洁清晰,特点之一是强制用空白符(white space)做为语句缩进。Python具备丰富和强大的库。它常被昵称为胶水语言,可以把用其余语言制做的各类模块(尤为是C/C++)很轻松地联结在一块儿。常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),而后对其中[3] 有特别要求的部分,用更合适的语言改写,好比3D游戏中的图形渲染模块,性能要求特别高,就能够用C/C++重写,然后封装为Python能够调用的扩展类库。须要注意的是在您使用扩展类库时可能须要考虑平台问题,某些可能不提供跨平台的实现。java
自从20世纪90年代初Python语言诞生至今,它已被逐渐普遍应用于系统管理任务的处理和Web编程。python
Python的创始人为Guido van Rossum。1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC 语言的一种继承。之因此选中Python(大蟒蛇的意思)做为该编程语言的名字,是由于他是一个叫Monty Python的喜剧团体的爱好者。mysql
ABC是由Guido参加设计的一种教学语言。就Guido本人看来,ABC 这种语言很是优美和强大,是专门为非专业程序员设计的。可是ABC语言并无成功,究其缘由,Guido 认为是其非开放形成的。Guido 决心在Python 中避免这一错误。同时,他还想实如今ABC 中闪现过但不曾实现的东西。linux
就这样,Python在Guido手中诞生了。能够说,Python是从ABC发展起来,主要受到了Modula-3(另外一种至关优美且强大的语言,为小型团体所设计的)的影响。而且结合了Unix shell和C的习惯。git
Python[4] 已经成为最受欢迎的程序设计语言之一。2011年1月,它被TIOBE编程语言排行榜评为2010年度语言。自从2004年之后,python的使用率呈线性增加[5] 。程序员
因为Python语言的简洁性、易读性以及可扩展性,在国外用Python作科学计算的研究机构日益增多,一些知名大学已经采用Python来教授程序设计课程。例如卡耐基梅隆大学的编程基础、麻省理工学院的计算机科学及编程导论就使用Python语言讲授。众多开源的科学计算软件包都提供了Python的调用接口,例如著名的计算机视觉库OpenCV、三维可视化库VTK、医学图像处理库ITK。而Python专用的科学计算扩展库就更多了,例如以下3个十分经典的科学计算扩展库:NumPy、SciPy和matplotlib,它们分别为Python提供了快速数组处理、数值运算以及绘图功能。所以Python语言及其众多的扩展库所构成的开发环境十分适合工程技术、科研人员处理实验数据、制做图表,甚至开发科学计算应用程序。web
提及科学计算,首先会被提到的多是MATLAB。然而除了MATLAB的一些专业性很强的工具箱还没法替代以外,MATLAB的大部分经常使用功能均可以在Python世界中找到相应的扩展库。和MATLAB相比,用Python作科学计算有以下优势:正则表达式
● 首先,MATLAB是一款商用软件,而且价格不菲。而Python彻底免费,众多开源的科学计算库都提供了Python的调用接口。用户能够在任何计算机上免费安装Python及其绝大多数扩展库。算法
● 其次,与MATLAB相比,Python是一门更易学、更严谨的程序设计语言。它能让用户编写出更易读、易维护的代码。sql
● 最后,MATLAB主要专一于工程和科学计算。然而即便在计算领域,也常常会遇到文件管理、界面设计、网络通讯等各类需求。而Python有着丰富的扩展库,能够轻易完成各类高级任务,开发者能够用Python实现完整应用程序所需的各类功能。
一、Python的发音与拼写
二、Python的意思是蟒蛇,源于做者喜欢的一部电视剧 (C呢?)
三、Python的做者是Guido van Rossum(龟叔)
四、Python是龟叔在1989年圣诞节期间,为了打发无聊的圣诞节而用C编写的一个编程语言
五、Python正式诞生于1991年
六、 Python的解释器现在有多个语言实现,咱们经常使用的是CPython(官方版本的C语言实现),七、其余还有Jython(能够运行在Java平台)、IronPython(能够运行在.NET和Mono平台)、PyPy(Python实现的,支持JIT即时编译)
八、Python目前有两个版本,Python2和Python3,最新版分别为2.7.13和3.6.2,现阶段大部分公司用的是Python2,Life is shot, you need Python. 人生苦短,我用Python。
九、2018年8月份 编程语言用户量排行榜 :https://www.tiobe.com/tiobe-index/
l 简单————Python是一种表明简单主义思想的语言。阅读一个良好的Python程序就感受像是在读英语同样,尽管这个英语的要求很是严格!Python的这种伪代码本质是它最大的优势之一。它使你可以专一于解决问题而不是去搞明白语言自己。
l 易学————就如同你即将看到的同样,Python极其容易上手。前面已经提到了,Python有极其简单的语法。
l 免费、开源————Python是FLOSS(自由/开放源码软件)之一。简单地说,你能够自由地发布这个软件的拷贝、阅读它的源代码、对它作改动、把它的一部分用于新的自由软件中。FLOSS是基于一个团体分享知识的概念。这是为何Python如此优秀的缘由之一——它是由一群但愿看到一个更加优秀的Python的人创造并常常改进着的。
l 高层语言————当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节。
l 可移植性————因为它的开源本质,Python已经被移植在许多平台上(通过改动使它可以工做在不一样平台上)。若是你当心地避免使用依赖于系统的特性,那么你的全部Python程序无需修改就能够在下述任何平台上面运行。这些平台包括Linux、Windows、FreeBSD、Macintosh、Solaris、OS/二、Amiga、AROS、AS/400、BeOS、OS/390、z/OS、Palm OS、QNX、VMS、Psion、Acom RISC OS、VxWorks、PlayStation、Sharp Zaurus、Windows CE甚至还有PocketPC、Symbian以及Google基于linux开发的Android平台!
l 解释性————这一点须要一些解释。一个用编译性语言好比C或C++写的程序能够从源文件(即C或C++语言)转换到一个你的计算机使用的语言(二进制代码,即0和1)。这个过程经过编译器和不一样的标记、选项完成。当你运行你的程序的时候,链接/转载器软件把你的程序从硬盘复制到内存中而且运行。而Python语言写的程序不须要编译成二进制代码。你能够直接从源代码运行程序。在计算机内部,Python解释器把源代码转换成称为字节码的中间形式,而后再把它翻译成计算机使用的机器语言并运行。事实上,因为你再也不须要担忧如何编译程序,如何确保链接转载正确的库等等,全部这一切使得使用Python更加简单。因为你只须要把你的Python程序拷贝到另一台计算机上,它就能够工做了,这也使得你的Python程序更加易于移植。
l 面向对象————Python既支持面向过程的编程也支持面向对象的编程。在“面向过程”的语言中,程序是由过程或仅仅是可重用代码的函数构建起来的。在“面向对象”的语言中,程序是由数据和功能组合而成的对象构建起来的。与其余主要的语言如C++和Java相比,Python以一种很是强大又简单的方式实现面向对象编程。
l 可扩展性————若是你须要你的一段关键代码运行得更快或者但愿某些算法不公开,你能够把你的部分程序用C或C++编写,而后在你的Python程序中使用它们。
l 丰富的库————Python标准库确实很庞大。它能够帮助你处理各类工做,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其余与系统有关的操做。记住,只要安装了Python,全部这些功能都是可用的。这被称做Python的“功能齐全”理念。除了标准库之外,还有许多其余高质量的库,如wxPython、Twisted和Python图像库等等。
l 规范的代码————Python采用强制缩进的方式使得代码具备极佳的可读性。
l Web应用开发
Python常常被用于Web开发。好比,经过mod_wsgi模块,Apache能够运行用Python编写的Web程序。Python定义了WSGI标准应用接口来协调Http服务器与基于Python的Web程序之间的通讯。一些Web框架,如Django,TurboGears,web2py,Zope等,可让程序员轻松地开发和管理复杂的Web程序。
l 操做系统管理、服务器运维的自动化脚本
在不少操做系统里,Python是标准的系统组件。 大多数Linux发行版以及NetBSD、OpenBSD和Mac OS X都集成了Python,能够在终端下直接运行Python。有一些Linux发行版的安装器使用Python语言编写,好比Ubuntu的Ubiquity安装器,Red Hat Linux和Fedora的Anaconda安装器。Gentoo Linux使用Python来编写它的Portage包管理系统。Python标准库包含了多个调用操做系统功能的库。经过pywin32这个第三方软件 包,Python可以访问Windows的COM服务及其它Windows API。使用IronPython,Python程序可以直接调用.Net Framework。通常说来,Python编写的系统管理脚本在可读性、性能、代码重用度、扩展性几方面都优于普通的shell脚本。
l 科学计算机器学习
NumPy,SciPy,Matplotlib可让Python程序员编写科学计算程序。
l 服务器软件(网络软件)——阿里云
Python对于各类网络协议的支持很完善,所以常常被用于编写服务器软件、网络爬虫。第三方库Twisted支持异步网络编程和多数标准的网络协议(包含客户端和服务器),而且提供了多种工具,被普遍用于编写高性能的服务器软件。
一、python网址:https://www.python.org/
二、anaconda网址:https://www.anaconda.com/
注意:Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。
一、Python安装比较简单,只须要双击安装便可,安装比较快(window)
二、anaconda一样是双击安装,可是安装过程的时间比较长,须要不少依赖项(window)
一、eclipse插件安装
Help—> eclipse marketplace—> pydev(较慢)
插件包:加压拷贝到eclipse的dropins中,重启便可
二、pycharm安装
傻瓜式安装,建立新的项目的时候直接选择sdk
一、在任意的IDE中建立Python项目
二、建立Python file文件
三、输入代码 print(“hello ,python”)
四、右击直接运行,会在控制台看到对应的结果
一、python:在cmd中直接输入python(配置环境变量)
二、ipython:找到对应的ipython的执行文件,直接执行
Ipython:支持变量自动补全,自动缩进,支持 bash shell 命令,内置了许多颇有用的功能和函数
注意:Python中自己不带有这个ipython的交互,须要自行安装。首先查看计算机中是否包含pip,通常安装完以后有,执行python –m pip install –upgrade pip,先将pip进行更新,而后安装ipython:pip install ipython
一、单行注释:以#开头,#右边的全部东西当作说明,而不是真正要执行的程序,起辅助说明做用
二、多行注释:’’’多行注释’’’能够写多行的功能说明
三、Python乱码问题
因为Python源代码也是一个文本文件,因此,当你的源代码中包含中文的时候,在保存源代码时,就须要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,咱们一般在文件开头写上这两行:
# -*- coding:utf-8 -*-
# coding=utf-8
一、变量的定义
在程序中,有时咱们须要对2个数据进行求和,那么该怎样作呢?
你们类比一下现实生活中,好比去超市买东西,每每我们须要一个菜篮子,用来进行存储物品,等到全部的物品都购买完成后,在收银台进行结帐便可
若是在程序中,须要把2个数据,或者多个数据进行求和的话,那么就须要把这些数据先存储起来,而后把它们累加起来便可
在Python中,存储一个数据,须要一个叫作变量的东西:
例如: num1=100
Num2=87
Result=num1+num2
变量三要素:变量的名称,变量的类型,变量的值
二、变量的类型
为了更充分的利用内存空间以及更有效率的管理内存,变量是有不一样的类型,如图所示
注意:
整数
Python能够处理任意大小的整数,固然包括负整数,在程序中的表示方法和数学上的写法如出一辙,例如:1,100,-8080,0,等等。
计算机因为使用二进制,因此,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。
浮点数
浮点数也就是小数,之因此称为浮点数,是由于按照科学记数法表示时,一个浮点数的小数点位置是可变的,好比,1.23x109和12.3x108是彻底相等的。浮点数能够用数学写法,如1.23,3.14,-9.01,等等。可是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012能够写成1.2e-5,等等。
整数和浮点数在计算机内部存储的方式是不一样的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的偏差。
字符串
字符串是以单引号'或双引号"括起来的任意文本,好比'abc',"xyz"等等。请注意,''或""自己只是一种表示方式,不是字符串的一部分,所以,字符串'abc'只有a,b,c这3个字符。若是'自己也是一个字符,那就能够用""括起来,好比"I'm OK"包含的字符是I,',m,空格,O,K这6个字符。
若是字符串内部既包含'又包含"怎么办?能够用转义字符\来标识,好比:
'I\'m \"OK\"!'
表示的字符串内容是:
I'm "OK"!
转义字符\能够转义不少字符,好比\n表示换行,\t表示制表符,字符\自己也要转义,因此\\表示的字符就是\,能够在Python的交互式命令行用print()打印字符串看看:
若是字符串里面有不少字符都须要转义,就须要加不少\,为了简化,Python还容许用r''表示''内部的字符串默认不转义,能够本身试试:
若是字符串内部有不少换行,用\n写在一行里很差阅读,为了简化,Python容许用'''...'''的格式表示多行内容,
print('''line1
line2
line3''')
布尔值
布尔值和布尔代数的表示彻底一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,能够直接用True、False表示布尔值(请注意大小写),也能够经过布尔运算计算出来
布尔值能够用and、or和not运算。
and运算是与运算,只有全部都为True,and运算结果才是True:
空值
空值是Python里一个特殊的值,用None表示。None不能理解为0,由于0是有意义的,而None是一个特殊的空值。
此外,Python还提供了列表、字典等多种数据类型,还容许建立自定义数据类型,咱们后面会继续讲到。
怎样知道一个变量的类型呢?
在python中,只要定义了一个变量,并且它有数据,那么它的类型就已经肯定了,不须要我们开发者主动的去说明它的类型,系统会自动辨别
能够使用type(变量的名字),来查看变量的类型
三、常见的数据类型转换
函数 |
说明 |
int(x [,base ]) |
将x转换为一个整数 |
long(x [,base ]) |
将x转换为一个长整数 |
float(x ) |
将x转换到一个浮点数 |
complex(real [,imag ]) |
建立一个复数 |
str(x ) |
将对象 x 转换为字符串 |
repr(x ) |
将对象 x 转换为表达式字符串 |
eval(str ) |
用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s ) |
将序列 s 转换为一个元组 |
list(s ) |
将序列 s 转换为一个列表 |
chr(x ) |
将一个整数转换为一个字符 |
unichr(x ) |
将一个整数转换为Unicode字符 |
ord(x ) |
将一个字符转换为它的整数值 |
hex(x ) |
将一个整数转换为一个十六进制字符串 |
oct(x ) |
将一个整数转换为一个八进制字符串 |
一、标识符
开发人员在程序中自定义的一些符号和名称,标示符是本身定义的,如变量名 、函数名等
二、标示符的规则
标示符由字母、下划线和数字组成,且数字不能开头。不能有特殊符号:\,/,;,#
思考:下面的标示符哪些是正确的,哪些不正确为何
fromNo12 from#12 my_Boolean my-Boolean Obj2 2ndObj myInt test1 Mike2jack My_tExt _test test!32haha(da)ttint jack_rose jack&rose GUI G.U.I
python中的标识符是区分大小写的
三、命名规则
见名知意
起一个有意义的名字,尽可能作到看一眼就知道是什么意思(提升代码可 读性) 好比: 名字 就定义为 name , 定义学生 用 student
驼峰命名法 :
小驼峰式命名法(lower camel case): 第一个单词以小写字母开始;第二个单词的首字母大写,例如:myName、aDog
大驼峰式命名法(upper camel case): 每个单字的首字母都采用大写字母,例如:FirstName、LastName
不过在程序员中还有一种命名法比较流行,就是用下划线“_”来链接全部的单词,好比send_buf
四、关键字
python一些具备特殊功能的标示符,这就是所谓的关键字
关键字,是python已经使用的了,因此不容许开发者本身定义和关键字相同的名字的标示符
查看关键字:(保留字)
And as assert break class continue def
del elif else except exec finally for
from global if in import is lambda
not or pass print raise return try
while with yield
能够经过如下命令进行查看当前系统中python的关键字:
import keyword
keyword.kwlist
一、普通的输出
# 打印提示
print('hello world') System.out.println
用print()在括号中加上字符串,就能够向屏幕上输出指定的文字。好比输出'hello, world',用代码实现以下:
>>> print('hello, world')
print()函数也能够接受多个字符串,用逗号“,”隔开,就能够连成一串输出:
>>> print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog
print()会依次打印每一个字符串,遇到逗号“,”会输出一个空格,所以,输出的字符串是这样拼起来的:
print()也能够打印整数,或者计算结果:
>>> print(300)
300>>> print(100 + 200)
300
所以,咱们能够把计算100 + 200的结果打印得更漂亮一点:
>>> print('100 + 200 =', 100 + 200)
100 + 200 = 300
注意,对于100 + 200,Python解释器自动计算出结果300,可是,'100 + 200 ='是字符串而非数学公式,Python把它视为字符串,请自行解释上述打印结果。
二、格式化输出
最后一个常见的问题是如何输出格式化的字符串。咱们常常会输出相似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,因此,须要一种简便的格式化字符串的方式。
在Python中,采用的格式化方式和C语言是一致的,用%实现,举例以下:
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
你可能猜到了,%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。若是只有一个%?,括号能够省略。
常见的占位符有:
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
其中,格式化整数和浮点数还能够指定是否补0和整数与小数的位数:
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
若是你不太肯定应该用什么,%s永远起做用,它会把任何数据类型转换为字符串:
>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
有些时候,字符串里面的%是一个普通字符怎么办?这个时候就须要转义,用%%来表示一个%:
>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'
练习:编写程序
小明的成绩从去年的72分提高到了今年的85分,请计算小明成绩提高的百分点,并用字符串格式化显示出'xx.x%',只保留小数点后1位:
三、输入
若是要让用户从电脑输入一些字符怎么办?Python提供了一个input(),可让用户输入字符串,并存放到一个变量里
1. python2版本中
1.1 raw_input()
在Python中,获取键盘输入的数据的方法是采用 raw_input 函数。
看以下示例:
注意:
raw_input()的小括号中放入的是,提示信息,用来在获取数据以前给用户的一个简单提示
raw_input()在从键盘获取了数据之后,会存放到等号右边的变量中
raw_input()会把用户输入的任何值都做为字符串来对待
1.2 input()
input()函数与raw_input()相似,但其接受的输入做为是表达式。
input()接受表达式输入,并把表达式的结果赋值给等号左边的变量
raw_input()输入的都当成字符串(和Python3的input功能同样)
2. python3版本中
没有raw_input()函数,只有input()
而且 python3中的input与python2中的raw_input()功能同样
一、算术运算符
下面以a=10 ,b=20为例进行计算
运算符 |
描述 |
实例 |
+ |
加 |
两个对象相加 a + b 输出结果 30 |
- |
减 |
获得负数或是一个数减去另外一个数 a - b 输出结果 -10 |
* |
乘 |
两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 |
/ |
除 |
x除以y b / a 输出结果 2 |
// |
取整除 |
返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
% |
取余(取模) |
返回除法的余数 b % a 输出结果 0 |
** |
幂 |
返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000 |
>>> 9/2.0
4.5
>>> 9//2.0
4.0
二、赋值运算符
运算符 |
描述 |
实例 |
= |
赋值运算符 |
把=号右边的结果给左边的变量 num=1+2*3 结果num的值为7 |
>>> a, b = 1, 2
>>> a
1
>>> b
2
三、复合赋值运算符
运算符 |
描述 |
实例 |
+= |
加法赋值运算符 |
c += a 等效于 c = c + a |
-= |
减法赋值运算符 |
c -= a 等效于 c = c - a |
*= |
乘法赋值运算符 |
c *= a 等效于 c = c * a |
/= |
除法赋值运算符 |
c /= a 等效于 c = c / a |
%= |
取模赋值运算符 |
c %= a 等效于 c = c % a |
**= |
幂赋值运算符 |
c **= a 等效于 c = c ** a |
//= |
取整除赋值运算符 |
c //= a 等效于 c = c // a |
注意:Python中没有a++,a--,++a,--a等操做
四、逻辑运算符
运算符 |
逻辑表达式 |
描述 |
实例 |
and |
x and y |
布尔"与" - 若是 x 为 False,x and y 返回 False,不然它返回 y 的计算值。 |
(a and b) 返回 20。 |
or |
x or y |
布尔"或" - 若是 x 是 True,它返回 True,不然它返回 y 的计算值。 |
(a or b) 返回 10。 |
not |
not x |
布尔"非" - 若是 x 为 True,返回 False 。若是 x 为 False,它返回 True。 |
not(a and b) 返回 False |
五、比较(关系)运算符
运算符 |
描述 |
示例 |
== |
检查两个操做数的值是否相等,若是是则条件变为真。 |
如a=3,b=3则(a == b) 为 true. |
!= |
检查两个操做数的值是否相等,若是值不相等,则条件变为真。 |
如a=1,b=3则(a != b) 为 true. |
<> |
检查两个操做数的值是否相等,若是值不相等,则条件变为真。 |
如a=1,b=3则(a <> b) 为 true。这个相似于 != 运算符 |
> |
检查左操做数的值是否大于右操做数的值,若是是,则条件成立。 |
如a=7,b=3则(a > b) 为 true. |
< |
检查左操做数的值是否小于右操做数的值,若是是,则条件成立。 |
如a=7,b=3则(a < b) 为 false. |
>= |
检查左操做数的值是否大于或等于右操做数的值,若是是,则条件成立。 |
如a=3,b=3则(a >= b) 为 true. |
<= |
检查左操做数的值是否小于或等于右操做数的值,若是是,则条件成立。 |
如a=3,b=3则(a <= b) 为 true. |
练习:
由用输入一个学生的信息,(姓名,年龄,地址)。而后看看年龄是不是偶数,而后输出。
计算机之因此能作不少自动化的任务,由于它能够本身作条件判断。
elif是else if的缩写,彻底能够有多个elif,因此if语句的完整形式就是:
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
好比,输入用户年龄,根据年龄打印不一样的内容,在Python程序中,用if语句实现:
age = 20
if age >= 18:
print('your age is', age)
print('adult')
根据Python的缩进规则,若是if语句判断是True,就把缩进的两行print语句执行了,不然,什么也不作。
也能够给if添加一个else语句,意思是,若是if判断是False,不要执行if的内容,去把else执行了:
age = 3
if age >= 18:
print('your age is', age)
print('adult')
else:
print('your age is', age)
print('teenager')
注意不要少写了冒号:。
固然上面的判断是很粗略的,彻底能够用elif作更细致的判断:
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
if判断条件还能够简写,好比写:
if x:
print('True')
只要x是非零数值、非空字符串、非空list等,就判断为True,不然为False。
最后看一个有问题的条件判断。不少同窗会用input()读取用户的输入,这样能够本身输入,程序运行得更有意思:
birth = input('birth: ')
if birth < 2000:
print('00前')
else:
print('00后')
输入1982,结果报错:
这是由于input()返回的数据类型是str,str不能直接和整数比较,必须先把str转换成整数。Python提供了int()函数来完成这件事情:
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00后')
再次运行,就能够获得正确地结果。可是,若是输入abc呢?又会获得一个错误信息:
Traceback (most recent calllast):
File "<stdin>", line 1, in <module>
ValueError: invalid literal forint() with base 10: 'abc'
原来int()函数发现一个字符串并非合法的数字时就会报错,程序就退出了。
如何检查并捕获程序运行期的错误呢?后面的错误和调试会讲到。
if 条件1:
知足条件1 作的事情1
知足条件1 作的事情2
...(省略)...
if 条件2:
知足条件2 作的事情1
知足条件2 作的事情2
...(省略)...
说明:
外层的if判断,也能够是if-else
内层的if判断,也能够是if-else
根据实际开发的状况,进行选择
练习
一、要求:从键盘输入刀子的长度,若是刀子长度没有超过10cm,则容许上火车,不然不容许上火车
二、
二、小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:
低于18.5:太轻
18.5-25:正常
25-28:太重
28-32:肥胖
高于32:严重肥胖
用if-elif判断并打印结果:
三、情节描述:上公交车,而且能够有座位坐下
要求:输入公交卡当前的余额,只要超过2元,就能够上公交车;若是空座位的数量大于0,就能够坐下
一、循环介绍
要计算1+2+3,咱们能够直接写表达式:
>>> 1 + 2 + 3=6
要计算1+2+3+...+10,勉强也能写出来。
可是,要计算1+2+3+...+10000,直接写表达式就不可能了。
为了让计算机能计算成千上万次的重复运算,咱们就须要循环语句。
Python的循环有两种,一种是for...in循环,另一种是while循环。
二、while循环
while循环的格式
while 条件:
条件知足时,作的事情1
条件知足时,作的事情2
条件知足时,作的事情3
...(省略)...
pass 和while没有关系
while循环应用
1. 计算1~100的累积和(包含1和100)
参考代码以下:
#encoding=utf-8
i = 1
sum = 0
while i<=100:
sum = sum + i
i += 1
print("1~100的累积和为:%d"%sum)
2. 计算1~100之间偶数的累积和(包含1和100)
一、循环次数(while中循环次数由条件决定)
二、在循环过程当中作什么
三、变量怎么变化?
三、while循环嵌套
前面学习过if的嵌套了,想想if嵌套是什么样子的?
相似if的嵌套,while嵌套就是:while里面还有while
<1>while嵌套的格式
while 条件1:
条件1知足时,作的事情1
条件1知足时,作的事情2
条件1知足时,作的事情3
...(省略)...
while 条件2:
条件2知足时,作的事情1
条件2知足时,作的事情2
条件2知足时,作的事情3
...(省略)...
<2>while嵌套应用一
要求:打印以下图形: m行,每行打印n次,n==m
*
* *
* * *
* * * *
* * * * *
<3>while嵌套应用二:九九乘法表
四、for循环
像while循环同样,for能够完成循环的功能。
在Python中 for循环能够遍历任何序列的项目,如一个列表或者一个字符串等。
for循环的格式
for 临时变量 in 列表或者字符串等:
循环知足条件时执行的代码
else:
循环不知足条件时执行的代码
五、break和continue
一、break
在循环中,break语句能够提早退出循环。例如,原本要循环打印1~100的数字:
n = 1 while n <=100: print(n) n = n + 1 print('END') |
上面的代码能够打印出1~100。
若是要提早结束循环,能够用break语句:
n = 1 while n <= 100: if n > 10: # 当n = 11时,条件知足,执行break语句 break # break语句会结束当前循环print(n) n = n + 1 print('END') |
执行上面的代码能够看到,打印出1~10后,紧接着打印END,程序结束。
可见break的做用是提早结束循环。
二、continue
在循环过程当中,也能够经过continue语句,跳过当前的此次循环,直接开始下一次循环。
n = 0
while n < 10:
n = n + 1
print(n)
上面的程序能够打印出1~10。可是,若是咱们想只打印奇数,能够用continue语句跳过某些循环:
n = 0
while n < 10:
n = n + 1
if n % 2 == 0: # 若是n是偶数,执行continue语句continue# continue语句会直接继续下一轮循环,后续的print()语句不会执行print(n)
执行上面的代码能够看到,打印的再也不是1~10,而是1,3,5,7,9。
可见continue的做用是提早结束本轮循环,并直接开始下一轮循环。
六、小结
循环是让计算机作重复任务的有效的方法。
break语句能够在循环过程当中直接退出循环,而continue语句能够提早结束本轮循环,并直接开始下一轮循环。这两个语句一般都必须配合if语句使用。
要特别注意,不要滥用break和continue语句。break和continue会形成代码执行逻辑分叉过多,容易出错。大多数循环并不须要用到break和continue语句,上面的两个例子,均可以经过改写循环条件或者修改循环逻辑,去掉break和continue语句。
有些时候,若是代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时能够用Ctrl+C退出程序,或者强制结束Python进程。
一、下标索引
所谓下标,就是编号,就比如超市中的存储柜的编号,经过这个编号就能找到相应的存储空间
字符串实际上就是字符的数组,因此也支持下标索引。
若是有字符串:name = 'abcdef',在内存中的实际存储以下:
若是想取出部分字符,那么能够经过下标的方法,(注意python中下标从 0 开始)
name = 'abcdef' print(name[0]) print(name[1]) print(name[-2]) |
二、切片(分片)
切片是指对操做的对象截取其中一部分的操做。字符串、列表、元组都支持切片操做。
切片的语法:[起始:结束:步长]
步长:表示下标变化的规律。
注意:选取的区间属于左闭右开型,即从"起始"位开始,到"结束"位的前一位结束(不包含结束位自己)。
咱们以字符串为例讲解。
若是取出一部分,则能够在中括号[]中,使用:
name = 'abcdef' print(name[0:3]) # 取 下标0~2 的字符 name = 'abcdef' print(name[0:5]) # 取 下标为0~4 的字符 name = 'abcdef' print(name[3:5]) # 取 下标为三、4 的字符 name = 'abcdef' print(name[2:]) # 取 下标为2开始到最后的字符 name = 'abcdef' print(name[1:-1]) # 取 下标为1开始 到 最后第2个 之间的字符 >>> a = "abcdef" >>> a[:3] 'abc' >>> a[::2] 'ace' >>> a[5:1:2] '' >>> a[1:5:2] 'bd' >>> a[::-2] 'fdb' >>> a[5:1:-2] 'fd' |
三、字符串常见操做
若有字符串mystr = 'hello world and bjsxt yunshuxueyuan sxt beijing',如下是常见的操做
<1>find == java Indexof方法
检测 str 是否包含在 mystr中,若是是返回开始的索引值,不然返回-1
mystr.find(str, start=0, end=len(mystr))
<2>index
跟find()方法同样,只不过若是str不在 mystr中会报一个异常.
mystr.index(str, start=0, end=len(mystr))
<3>count
返回 str在start和end之间 在 mystr里面出现的次数
mystr.count(str, start=0, end=len(mystr))
<4>replace
把 mystr 中的 str1 替换成 str2,若是 count 指定,则替换不超过 count 次.
mystr.replace(str1, str2, mystr.count(str1))
<5>split
以 str 为分隔符切片 mystr,若是 maxsplit有指定值,则仅分隔 maxsplit 个子字符串
mystr.split(str=" ", 2)
<6>capitalize
把字符串的第一个字符大写
mystr.capitalize()
<7>title
把字符串的每一个单词首字母大写
<8>startswith
检查字符串是不是以 obj 开头, 是则返回 True,不然返回 False
mystr.startswith(obj)
<9>endswith
检查字符串是否以obj结束,若是是返回True,不然返回 False.
mystr.endswith(obj)
<10>lower
转换 mystr 中全部大写字符为小写
mystr.lower()
<11>upper
转换 mystr 中的小写字母为大写
mystr.upper()
<12>ljust
返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
mystr.ljust(width)
<13>rjust
返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
mystr.rjust(width)
<14>center
返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
mystr.center(width)
<15>lstrip
删除 mystr 左边的空白字符
mystr.lstrip()
<16>rstrip
删除 mystr 字符串末尾的空白字符
mystr.rstrip()
<17>strip ---java trim
删除mystr字符串两端的空白字符
<18>rfind
相似于 find()函数,不过是从右边开始查找.
mystr.rfind(str, start=0,end=len(mystr) )
<19>rindex
相似于 index(),不过是从右边开始.
mystr.rindex( str, start=0,end=len(mystr))
<20>partition
把mystr以str分割成三部分,str前,str和str后
mystr.partition(str)
<21>rpartition
相似于 partition()函数,不过是从右边开始.
mystr.rpartition(str)
<22>splitlines
按照换行符分隔,返回一个包含各行做为元素的列表
mystr.splitlines()
<23>isalpha
若是 mystr 全部字符都是字母 则返回 True,不然返回 False
mystr.isalpha()
<24>isdigit
若是 mystr 只包含数字则返回 True 不然返回 False.
mystr.isdigit()
<25>isalnum
若是 mystr 全部字符都是字母或数字则返回 True,不然返回 False
mystr.isalnum()
<26>isspace
若是 mystr 中只包含空格,则返回 True,不然返回 False.
mystr.isspace()
<27>join
mystr 中每一个字符后面插入list的每一个元素后面,构造出一个新的字符串
mystr.join(list)
总结:
查找字符串:
find:找不到返回-1 ,都是从左边找,右边查找r
index:找不到报错
1、列表介绍
Python内置的一种数据类型是列表:list。list是一种有序的集合,能够随时添加和删除其中的元素。
好比,列出班里全部同窗的名字,就能够用一个list表示:
>>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates ['Michael', 'Bob', 'Tracy'] |
变量classmates就是一个list。用len()函数能够得到list元素的个数:
>>> len(classmates) 3 |
用索引来访问list中每个位置的元素,记得索引是从0开始的:
>>> classmates[0] 'Michael' >>> classmates[1] 'Bob' >>> classmates[2] 'Tracy' >>> classmates[3] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range |
当索引超出了范围时,Python会报一个IndexError错误,因此,要确保索引不要越界,记得最后一个元素的索引是len(classmates) - 1。
若是要取最后一个元素,除了计算索引位置外,还能够用-1作索引,直接获取最后一个元素:
>>> classmates[-1] 'Tracy' |
以此类推,能够获取倒数第2个、倒数第3个:
2、列表的相关操做
列表中存放的数据是能够进行修改的,好比"增"、"删"、"改""
<1>添加元素("增"append, extend, insert)
append
经过append能够向列表添加元素
extend(+)
经过extend能够将另外一个集合中的元素逐一添加到列表中
>>> a = [1, 2] >>> b = [3, 4] >>> a.append(b) >>> a [1, 2, [3, 4]] >>> a.extend(b) >>> a [1, 2, [3, 4], 3, 4]
|
insert
insert(index, object) 在指定位置index前插入元素object
>>> a = [0, 1, 2] >>> a.insert(1, 3) >>> a [0, 3, 1, 2]
|
<2>修改元素("改")
修改元素的时候,要经过下标来肯定要修改的是哪一个元素,而后才能进行修改
<3>查找元素("查"in, not in, index, count)
所谓的查找,就是看看指定的元素是否存在
in, not in
python中查找的经常使用方法为:
in(存在),若是存在那么结果为true,不然为false
not in(不存在),若是不存在那么结果为true,不然false
#查找是否存在if findName in nameList:
print('在字典中找到了相同的名字')
else:
print('没有找到')
说明:
in的方法只要会用了,那么not in也是一样的用法,只不过not in判断的是不存在
index, count
index和count与字符串中的用法相同
>>> a = ['a', 'b', 'c', 'a', 'b'] >>> a.index('a', 1, 3) # 注意是左闭右开区间 Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 'a'isnotin list >>> a.index('a', 1, 4) 3>>> a.count('b') 2>>> a.count('d') 0 |
<4>删除元素("删"del, pop, remove)
类比现实生活中,若是某位同窗调班了,那么就应该把这个条走后的学生的姓名删除掉;在开发中常常会用到删除这种功能。
列表元素的经常使用删除方法有:
del:根据下标进行删除,其实能够删除全部变量
pop:默认删除最后一个元素
remove:根据元素的值进行删除第一个
>>> l ['abcdef', ['aaa', 'bb', 'ccc'], 'ddd', 'fff'] >>> del l[0] >>> l [['aaa', 'bb', 'ccc'], 'ddd', 'fff'] |
<5>排序(sort, reverse)
sort方法是将list按特定顺序从新排列,默认为由小到大,参数reverse=True可改成倒序,由大到小。
reverse方法是将list逆置。
>>> a = [1, 4, 2, 3] >>> a [1, 4, 2, 3] >>> a.reverse() >>> a [3, 2, 4, 1] >>> a.sort() >>> a [1, 2, 3, 4] >>> a.sort(reverse=True) >>> a [4, 3, 2, 1] |
<6>enumerate()
>>> chars = ['a', 'b', 'c', 'd'] >>> for i, chr in enumerate(chars): ... print i, chr ... 0 a 1 b 2 c 3 d
|
Python的元组与列表相似,不一样之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。
>>> aTuple = ('et',77,99.9) >>> aTuple ('et',77,99.9) |
若是要定义一个空的tuple,能够写成():
>>> t = () >>> t () |
可是,要定义一个只有1个元素的tuple,若是你这么定义:
>>> t = (1) >>> t 1 |
定义的不是tuple,是1这个数!这是由于括号()既能够表示tuple,又能够表示数学公式中的小括号,这就产生了歧义,所以,Python规定,这种状况下,按小括号进行计算,计算结果天然是1。
因此,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
>>> t = (1,) >>> t (1,) |
Python在显示只有1个元素的tuple时,也会加一个逗号,,以避免你误解成数学计算意义上的括号。
最后来看一个“可变的”tuple:
>>> t = ('a', 'b', ['A', 'B']) >>> t[2][0] = 'X' >>> t[2][1] = 'Y' >>> t ('a', 'b', ['X', 'Y']) |
这个tuple定义的时候有3个元素,分别是'a','b'和一个list。不是说tuple一旦定义后就不可变了吗?怎么后来又变了?
别急,咱们先看看定义的时候tuple包含的3个元素:
当咱们把list的元素'A'和'B'修改成'X'和'Y'后,tuple变为:
表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并无改为别的list,因此,tuple所谓的“不变”是说,tuple的每一个元素,指向永远不变。即指向'a',就不能改为指向'b',指向一个list,就不能改为指向其余对象,但指向的这个list自己是可变的!
理解了“指向不变”后,要建立一个内容也不变的tuple怎么作?那就必须保证tuple的每个元素自己也不能变。
<1>访问元组
<2>修改元组
说明: python中不容许修改元组的数据,包括不能删除其中的元素。
<3>元组的内置函数count, index
index和count与字符串和列表中的用法相同
>>> a = ('a', 'b', 'c', 'a', 'b') >>> a.index('a', 1, 3) # 注意是左闭右开区间 Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: tuple.index(x): x notin tuple >>> a.index('a', 1, 4) 3 >>> a.count('b') 2 >>> a.count('d') 0 |
一、字典的介绍
Python内置了字典:dict的支持,dict全称dictionary,在其余语言中也称为map,使用键-值(key-value)存储,具备极快的查找速度。
举个例子,假设要根据同窗的名字查找对应的成绩,若是用list实现,须要两个list:
names = ['Michael', 'Bob', 'Tracy'] scores = [95, 75, 85] |
给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长。
若是用dict实现,只须要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,不管这个表有多大,查找速度都不会变慢。用Python写一个dict以下:
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95 |
软件开发中的字典
变量info为字典类型:
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}
说明:
l 字典和列表同样,也可以存储多个数据
l 列表中找某个元素时,是根据下标进行的
l 字典中找某个元素时,是根据'名字'(就是冒号:前面的那个值,例如上面代码中的'name'、'id'、'sex')
l 字典的每一个元素由2部分组成,键:值。例如 'name':'班长' ,'name'为键,'班长'为值
若访问不存在的键,则会报错:
>>> info['age']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'age'
在咱们不肯定字典中是否存在某个键而又想获取其值时,能够使用get方法,还能够设置默认值:
>>> age = info.get('age') >>> age #'age'键不存在,因此age为None>>> type(age) <type 'NoneType'> >>> age = info.get('age', 18) # 若info中不存在'age'这个键,就返回默认值18 >>> age 18 |
二、字典的常见操做
<1>修改元素
字典的每一个元素中的数据是能够修改的,只要经过key找到,便可修改
demo:
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'} newId = input('请输入新的学号') info['id'] = int(newId) print('修改以后的id为%d:'%info['id'] |
<2>添加元素
demo:访问不存在的元素
info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'} print('id为:%d'%info['id']) |
结果:
若是在使用 变量名['键'] = 数据 时,这个“键”在字典中,不存在,那么就会新增这个元素
demo:添加新的元素
info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'} # print('id为:%d'%info['id'])#程序会终端运行,由于访问了不存在的键 newId = input('请输入新的学号') info['id'] = newId print('添加以后的id为:%d'%info['id']) |
结果:
请输入新的学号188 添加以后的id为: 188 |
<3>删除元素
对字典进行删除操做,有一下几种:
del
clear()
demo:del删除指定的元素
info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'} print('删除前,%s'%info['name']) del info['name'] print('删除后,%s'%info['name']) |
demo:del删除整个字典
info = {'name':'monitor', 'sex':'f', 'address':'China'} print('删除前,%s'%info) del info print('删除后,%s'%info) |
demo:clear清空整个字典
三、字典的常见函数:
<1>len()
测量字典中,键值对的个数
<2>keys == map.keySet()
返回一个包含字典全部KEY的列表
<3>values
返回一个包含字典全部value的列表
<4>items
返回一个包含全部(键,值)元祖的列表
<5>has_key (python2.7版本) == in 条件表达式
dict.has_key(key)若是key在字典中,返回True,不然返回False
四、字典遍历
<1> 遍历字典的key(键)
<2> 遍历字典的value(值)
<3> 遍历字典的项(元素)
<4> 遍历字典的key-value(键值对)
六、总结:
一、请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
二、和list比较,dict有如下几个特色:
1)查找和插入的速度极快,不会随着key的增长而变慢;
2)须要占用大量的内存,内存浪费多。
3)而list相反:查找和插入的时间随着元素的增长而增长;占用空间小,浪费内存不多。
因此,dict是用空间来换取时间的一种方法。
三、dict能够用在须要高速查找的不少地方,在Python代码中几乎无处不在,正确使用dict很是重要,须要牢记的第一条就是dict的key必须是不可变对象。这是由于dict根据key来计算value的存储位置,若是每次计算相同的key得出的结果不一样,那dict内部就彻底混乱了。这个经过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,做为key的对象就不能变。在Python中,字符串、整数等都是不可变的,所以,能够放心地做为key。而list是可变的,就不能做为key
上面咱们讲了,str是不变对象,而list是可变对象。
对于可变对象,好比list,对list进行操做,list内部的内容是会变化的,好比:
>>> a = ['c', 'b', 'a'] >>> a.sort() >>> a ['a', 'b', 'c'] |
而对于不可变对象,好比str,对str进行操做呢:
>>> a = 'abc' >>> a.replace('a', 'A') 'Abc' >>> a 'abc' |
虽然字符串有个replace()方法,也确实变出了'Abc',但变量a最后还是'abc',应该怎么理解呢?
咱们先把代码改为下面这样:
>>> a = 'abc' >>> b = a.replace('a', 'A') >>> b 'Abc'>>> a 'abc' |
要始终牢记的是,a是变量,而'abc'才是字符串对象!有些时候,咱们常常说,对象a的内容是'abc',但实际上是指,a自己是一个变量,它指向的对象的内容才是'abc':
当咱们调用a.replace('a', 'A')时,实际上调用方法replace是做用在字符串对象'abc'上的,而这个方法虽然名字叫replace,但却没有改变字符串'abc'的内容。相反,replace方法建立了一个新字符串'Abc'并返回,若是咱们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串'abc',但变量b却指向新字符串'Abc'了:
因此,对于不变对象来讲,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会建立新的对象并返回,这样,就保证了不可变对象自己永远是不可变的。
总结:
一、可变类型,值能够改变:
列表 list
字典 dict
set (没有value的字典)
二、不可变类型,值不能够改变:
数值类型 int, long, bool, float
字符串 str
元组 tuple
咱们知道圆的面积计算公式为:S = πr2
当咱们知道半径r的值时,就能够根据公式计算出面积。假设咱们须要计算3个不一样大小的圆的面积:
r1 = 12.34 r2 = 9.08 r3 = 73.1
s1 = 3.14 * r1 * r1
s2 = 3.14 * r2 * r2
s3 = 3.14 * r3 * r3
当代码出现有规律的重复的时候,你就须要小心了,每次写3.14 * x * x不只很麻烦,并且,若是要把3.14改为3.14159265359的时候,得所有替换。
有了函数,咱们就再也不每次写s = 3.14 * x * x,而是写成更有意义的函数调用s = area_of_circle(x),而函数area_of_circle自己只须要写一次,就能够屡次调用。
基本上全部的高级语言都支持函数,Python也不例外。Python不但能很是灵活地定义函数,并且自己内置了不少有用的函数,能够直接调用。
1、定义函数
定义函数的格式以下:
def 函数名(): 代码
demo:
# 定义一个函数,可以完成打印信息的功能 def printInfo(): print'------------------------------------' print' 人生苦短,我用Python' print'------------------------------------' |
2、调用函数
定义了函数以后,就至关于有了一个具备某些功能的代码,想要让这些代码可以执行,须要调用它
调用函数很简单的,经过 函数名() 便可完成调用
demo:
# 定义完函数后,函数是不会自动执行的,须要调用它才能够 printInfo() |
思考一个问题,以下:
如今须要定义一个函数,这个函数可以完成2个数的加法运算,而且把结果打印出来,该怎样设计?下面的代码能够吗?有什么缺陷吗?
def add_2num(): a = 11 b = 22 c = a+b print c |
为了让一个函数更通用,即想让它计算哪两个数的和,就让它计算哪两个数的和,在定义函数的时候可让函数接收数据,就解决了这个问题,这就是 函数的参数
<1> 定义带有参数的函数
示例以下:
def add2num(a, b): c = a+b print c |
<2> 调用带有参数的函数
以调用上面的add2num(a, b)函数为例:
def add2num(a, b): c = a+b print c add2num(11, 22) #调用带有参数的函数时,须要在小括号中,传递数据 |
<3> 练一练
要求:定义一个函数,完成前2个数完成加法运算,而后对第3个数,进行减法;而后调用这个函数
使用def定义函数,要注意有3个参数
调用的时候,这个函数定义时有几个参数,那么就须要传递几个参数
<4> 小总结
定义时小括号中的参数,用来接收参数用的,称为 “形参”
调用时小括号中的参数,用来传递给函数用的,称为 “实参”
1. 缺省参数
调用函数时,缺省参数的值若是没有传入,则被认为是默认值。下例会打印默认的age,若是age没有被传入:
def printinfo( name, age = 35 ):# 打印任何传入的字符串 print"Name: ", name print"Age ", age # 调用printinfo函数 printinfo(name="miki" ) printinfo( age=9,name="miki" ) |
以上实例输出结果:
Name: miki Age 35 Name: miki Age 9 |
注意:带有默认值的参数必定要位于参数列表的最后面。
>>> defprintinfo(name, age=35, sex): ... print name ... File "<stdin>", line 1 SyntaxError: non-default argument follows default argument |
2.不定长参数
有时可能须要一个函数能处理比当初声明时更多的参数。这些参数叫作不定长参数,声明时不会命名。
基本语法以下:
Def functionname([formal_args,] *args, **kwargs):"函数_文档字符串" function_suite return [expression] |
加了星号(*)的变量args会存放全部未命名的变量参数,args为元组;而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。
>>> def fun(a, b, *args, **kwargs): ... """可变参数演示示例""" ... print"a =", a ... print"b =", b ... print"args =", args ... print"kwargs: " ... for key, value in kwargs.items(): ... print key, "=", value ... >>> fun(1, 2, 3, 4, 5, m=6, n=7, p=8) # 注意传递的参数对应 a = 1 b = 2 args = (3, 4, 5) kwargs: p = 8 m = 6 n = 7 >>> >>> c = (3, 4, 5) >>> d = {"m":6, "n":7, "p":8} >>> fun(1, 2, *c, **d) # 注意元组与字典的传参方式 a = 1 b = 2 args = (3, 4, 5) kwargs: p = 8 m = 6 n = 7 >>> >>> fun(1, 2, c, d) # 注意不加星号与上面的区别 a = 1 b = 2 args = ((3, 4, 5), {'p': 8, 'm': 6, 'n': 7}) kwargs: |
3. 引用传参
可变类型与不可变类型的变量分别做为函数参数时,会有什么不一样吗?
Python有没有相似C语言中的指针传参呢?
>>> def selfAdd(a):... """自增"""... a += a ... >>> a_int = 1 >>> a_int 1 >>> selfAdd(a_int) >>> a_int 1 >>> a_list = [1, 2] >>> a_list [1, 2] >>> selfAdd(a_list) >>> a_list [1, 2, 1, 2] |
Python中函数参数是引用传递(注意不是值传递)。对于不可变类型,因变量不能修改,因此运算不会影响到变量自身;而对于可变类型来讲,函数体中的运算有可能会更改传入的参数变量。
<1>带有返回值的函数
想要在函数中把结果返回给调用者,须要在函数中使用return
以下示例:
def add2num(a, b): c = a+b return c |
或者
def add2num(a, b): return a+b |
<2>保存函数的返回值
在本小节刚开始的时候,说过的“买烟”的例子中,最后儿子给你烟时,你必定是从儿子手中接过来 对么,程序也是如此,若是一个函数返回了一个数据,那么想要用这个数据,那么就须要保存
保存函数的返回值示例以下:
#定义函数 def add2num(a, b): return a+b #调用函数,顺便保存函数的返回值 result = add2num(100,98) #由于result已经保存了add2num的返回值,因此接下来就能够使用了 print result |
在python中咱们可不能够返回多个值?
>>> def divid(a, b): ... shang = a//b ... yushu = a%b ... return shang, yushu ... >>> sh, yu = divid(5, 2) >>> sh 5 >>> yu 1 |
本质是利用了元组
一、局部变量
局部变量(Local variables)指在程序中只在特定过程或函数中能够访问的变量。
总结
一、局部变量,就是在函数内部定义的变量
二、不一样的函数,能够定义相同的名字的局部变量,可是各用个的不会产生影响
三、局部变量的做用,为了临时保存数据须要在函数中定义变量来进行存储,这就是它的做用
二、全局变量
<1>什么是全局变量
若是一个变量,既能在一个函数中使用,也能在其余的函数中使用,这样的变量就是全局变量
<2>全局变量和局部变量名字相同问题
<3>修改全局变量
既然全局变量,就是可以在因此的函数中进行使用,那么能否进行修改呢?:global
<4>可变类型的全局变量
>>> a = 1 >>> deff(): ... a += 1 ... print a ... >>> f() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in f UnboundLocalError: local variable 'a' referenced before assignment >>> li = [1,] >>> deff2(): ... li.append(1) ... print li ... >>> f2() [1, 1] >>> li [1, 1] |
<5>总结1:
在函数外边定义的变量叫作全局变量
全局变量可以在全部的函数中进行访问
若是在函数中修改全局变量,那么就须要使用global进行声明,不然出错
若是全局变量的名字和局部变量的名字相同,那么使用的是局部变量的,小技巧:强龙不压地头蛇
<5>总结2:
在函数中不使用global声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
对于不可变类型的全局变量来讲,因其指向的数据不能修改,因此不使用global时没法修改全局变量。
对于可变类型的全局变量来讲,因其指向的数据能够修改,因此不使用global时也可修改全局变量。
可变类型:值能够修改(内存地址不变可是所保存的值变化了),引用能够修改(变量的内存地址变化了)
不可变类型:值不能够修改,能够修改变量的引用(=赋值号)。
在函数里面修改全局变量:
一、若是全局变量是可变类型:因此在函数里面任意修改(值,引用)
二、若是全局变量是不可变类型:在函数里面不能修改值,也不能修改引用,除非加上global才能修改引用。
<1>什么是递归函数
经过前面的学习知道一个函数能够调用其余函数。
在函数内部,能够调用其余函数。若是一个函数在内部调用自身自己,这个函数就是递归函数。
<2>递归函数的做用
举个例子,咱们来计算阶乘 n! = 1 * 2 * 3 * ... * n
解决办法1:
看阶乘的规律
1! = 1 2! = 2 × 1 = 2 × 1! 3! = 3 × 2 × 1 = 3 × 2! 4! = 4 × 3 × 2 × 1 = 4 × 3! ... n! = n × (n-1)!
解决办法2:
递归函数案例:
斐波拉契数列,该数列中有n个数字。
1 1 2 3 5 8
该数列中,从第三个数字开始:数值 =前一个数字 + 前前面一个数字
(n-1) + (n-2)
一、匿名函数
用lambda关键词能建立小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
lambda函数的语法只包含一个语句,以下:
lambda [arg1 [,arg2,.....argn]]: expression |
以下实例:
sum = lambda arg1, arg2: arg1 + arg2 #调用sum函数 print"Value of total : ", sum( 10, 20 ) print"Value of total : ", sum( 20, 20 ) |
以上实例输出结果:
Value of total : 30 Value of total : 40 |
Lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数不能直接调用print,由于lambda须要一个表达式
二、应用场合
函数做为参数传递
一、本身定义函数
>>> def fun(a, b, opt): ... print"a =", a ... print"b =", b ... print"result =", opt(a, b) ... >>> fun(1, 2, lambda x,y:x+y) a = 1 b = 2 result = 3 |
二、做为内置函数的参数
想想,下面的数据如何指定按age或name排序?
stus = [ {"name":"zhangsan", "age":18}, {"name":"lisi", "age":19}, {"name":"wangwu", "age":17} ] |
按name排序:
>>> stus.sort(key = lambda x:x['name']) >>> stus [{'age': 19, 'name': 'lisi'}, {'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}]
|
按age排序:
>>> stus.sort(key = lambda x:x['age']) >>> stus [{'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}, {'age': 19, 'name': 'lisi'}] |
想想:若是想用word编写一份简历,应该有哪些流程呢?
一、打开word软件,新建一个word文件
二、写入我的简历信息
三、保存文件
四、关闭word软件
一样,在操做文件的总体过程与使用word编写一份简历的过程是很类似的 (io操做)
一、打开文件,或者新创建一个文件
二、读/写数据
三、关闭文件
<1>打开文件
在python,使用open函数,能够打开一个已经存在的文件,或者建立一个新文件
open(文件名,访问模式)
示例以下:
f = open(r'd:\nata\test.txt', 'w') |
说明:
访问模式 |
说明 |
r |
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w |
打开一个文件只用于写入。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。 |
a |
打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb |
以二进制格式打开一个文件只用于写入。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。 |
ab |
以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ |
打开一个文件用于读写。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。 |
a+ |
打开一个文件用于读写。若是该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。若是该文件不存在,建立新文件用于读写。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ |
以二进制格式打开一个文件用于读写。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。 |
ab+ |
以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。若是该文件不存在,建立新文件用于读写。 |
<2>关闭文件
close( )
示例以下:
# 新建一个文件,文件名为: test.txt f = open('test.txt', 'w') # 关闭这个文件 f.close() |
<1>写数据(write)
使用write()能够完成向文件写入数据 demo: f = open('test.txt', 'w') f.write('hello world, i am here!') f.close() 注意:若是文件不存在那么建立,若是存在那么就先清空,而后写入数据 |
<2>读数据(read)
使用read(num)能够从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),若是没有传入num,那么就表示读取文件中全部的数据 demo: f = open('test.txt', 'r') content = f.read(1024) print(content) print("-"*30) content = f.read() print(content) f.close() 注意:若是open是打开一个文件,那么能够不用谢打开的模式,即只写 open('test.txt'),若是使用读了屡次,那么后面读取的数据是从上次读完后的位置开始的 |
<3>读数据(readlines)
就像read没有参数时同样,readlines能够按照行的方式把整个文件中的内容进行一次性读取,而且返回的是一个列表,其中每一行的数据为一个元素 #coding=utf-8 f = open('test.txt', 'r') content = f.readlines() print(type(content)) i=1 for temp in content: print("%d:%s"%(i, temp)) i+=1 f.close() |
<4>读数据(readline)
#coding=utf-8 f = open('test.txt', 'r') content = f.readline() print("1:%s"%content) content = f.readline() print("2:%s"%content) f.close() |
<1>获取当前读写的位置tell
在读写文件的过程当中,若是想知道当前的位置,能够使用tell()来获取 # 打开一个已经存在的文件 f = open("test.txt", "r") str = f.read(3) print"读取的数据是 : ", str # 查找当前位置 position = f.tell() print"当前文件位置 : ", position str = f.read(3) print"读取的数据是 : ", str # 查找当前位置 position = f.tell() print"当前文件位置 : ", position f.close() |
<2>定位到某个位置
若是在读写文件的过程当中,须要从另一个位置进行操做的话,能够使用seek() seek(offset, from)有2个参数 offset:偏移量 from:方向 0:表示文件开头 1:表示当前位置 2:表示文件末尾 demo:把位置设置为:从文件开头,偏移5个字节 # 打开一个已经存在的文件 f = open("test.txt", "r") str = f.read(30) print"读取的数据是 : ", str # 查找当前位置 position = f.tell() print"当前文件位置 : ", position # 从新设置位置 f.seek(5,0) # 查找当前位置 position = f.tell() print"当前文件位置 : ", position f.close() demo:把位置设置为:离文件末尾,3字节处 # 打开一个已经存在的文件 f = open("test.txt", "r") # 查找当前位置 position = f.tell() print"当前文件位置 : ", position # 从新设置位置 f.seek(-3,2) # 读取到的数据为:文件最后3个字节数据 str = f.read() print"读取的数据是 : ", str f.close() |
有些时候,须要对文件进行重命名、删除等操做,python的os模块中都有这么功能
import os
python编程时,常常和文件、目录打交道,这是就离不了os模块。os模块包含广泛的操做系统功能,与具体的平台无关。如下列举经常使用的命令
1. os.name()——判断如今正在实用的平台,Windows 返回 ‘nt'; Linux 返回’posix'
rename(须要修改的文件名, 新的文件名) 也能够作剪切。
2. os.getcwd()——获得当前工做的目录。
3. os.listdir()——指定全部目录下全部的文件和目录名。
以列表的形式所有列举出来,其中没有区分目录和文件。
4. os.remove()——删除指定文件
5. os.rmdir()——删除指定目录 :该目录不能为空
6. os.mkdir()——建立目录
注意:这样只能创建一层,要想递归创建可用:os.makedirs(x/y/z)
7. os.path.isfile()——判断指定对象是否为文件。是返回True,不然False
8. os.path.isdir()——判断指定对象是否为目录。是True,不然False。例:
9. os.path.exists()——检验指定的对象是否存在。是True,不然False.例:
10. os.path.split()——返回路径的目录和文件名。例:
此处只是把先后两部分分开而已。就是找最后一个'/'。看例子:
11. os.getcwd()——得到当前工做的目录(get current work dir)
12. os.system()——执行shell命令。例:
注意:此处运行shell命令时,若是要调用python以前的变量,能够用以下方式:
var=123 os.environ['var']=str(var) //注意此处[]内得是 “字符串” os.system('echo $var') |
13. os.chdir()——改变目录到指定目录
14. os.path.getsize()——得到文件的大小,若是为目录,返回0
15. os.path.abspath()——得到绝对路径。例:
16. os.path.join(path, name)——链接目录和文件名。例:
17.os.path.basename(path)——返回文件名
18. os.path.dirname(path)——返回文件所在目录
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象做为程序的基本单元,一个对象包含了数据和操做数据的函数。面向对象是一种对现实世界理解和抽象的方法。
“面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。“面向过程”也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特性(好比继承、多态、封装),而且它们不容许混合持久化状态和域逻辑。
就是分析出解决问题所须要的步骤,而后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就能够了。
面向过程是一件事“该怎么作“,面向对象是一件事“该让谁来作”,而后那个“谁”就是对象,他要怎么作是他本身的事,反正最后一群对象协力能把事作好就好了。
面向对象三个特性:继承,封装,多态。
面向对象编程的2个很是重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程当中,为了将具备共同特征和行为的一组对象抽象定义,提出了另一个新的概念——类
类就至关于制造飞机时的图纸,用它来进行建立的飞机就至关于对象
1. 类
人以类聚 物以群分。 具备类似内部状态和运动规律的实体的集合(或统称为抽象)。 具备相同属性和行为事物的统称
类是抽象的,在使用的时候一般会找到这个类的一个具体的存在,使用这个具体的存在。一个类能够找到多个对象
2. 对象
某一个具体事物的存在 ,在现实世界中能够是看得见摸得着的。 能够是直接使用的
3. 类和对象之间的关系
小总结:类就是建立对象的模板
4. 练习:区分类和对象
奔驰汽车 类
奔驰smart 类
张三的那辆奔驰smart 对象
狗 类
大黄狗 类
李四家那只大黄狗 对象
水果 类
苹果 类
红苹果 类
红富士苹果 类
我嘴里吃了一半的苹果 对象
5. 类的构成
类(Class) 由3个部分构成
类的名称:类名
类的属性:一组数据
类的方法:容许对进行操做的方法 (行为)
<1> 举例:
1)人类设计,只关心3样东西:
事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
方法(行为/功能):跑(run)、打架(fight)
2)狗类的设计
类名:狗(Dog)
属性:品种 、毛色、性别、名字、 腿儿的数量
方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
一、类的定义
定义一个类,格式以下:
class 类名: 方法列表
demo:定义一个Car类
# 定义类 classCar: # 方法 def getCarInfo(self): print('车轮子个数:%d, 颜色%s'%(self.wheelNum, self.color)) def move(self): print("车正在移动...") |
说明:
一、定义类时有2种:新式类和经典类,上面的Car为经典类,若是是Car(object)则为新式类
二、类名的命名规则按照"大驼峰"
二、建立对象
经过上一节课程,定义了一个Car类;就比如有车一个张图纸,那么接下来就应该把图纸交给生成工人们去生成了。
python中,能够根据已经定义的类去建立出一个个对象
建立对象的格式为:
对象名 = 类名()
建立对象demo:
# 定义类 class Car: # 移动 def move(self): print('车在奔跑...') # 鸣笛 def toot(self):#self能够不写self,方法中必须有且一个参数。第一个参数表示当前对象。名字随便取,可是习惯都写self print("车在鸣笛...嘟嘟..") # 建立一个对象,并用变量BMW来保存它的引用 BMW = Car() BMW.color = '黑色' BMW.wheelNum = 4#轮子数量 BMW.move() BMW.toot() print(BMW.color) print(BMW.wheelNum) |
总结:
一、BMW = Car(),这样就产生了一个Car的实例对象,必定在内存中有一块空间存放对象的数据信息。此时也能够经过实例对象BMW来访问属性或者方法
二、第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,若是后面再次出现BMW.color = xxx表示对属性进行修改
三、BMW是一个对象,它拥有属性(数据)和方法(函数)
四、当建立一个对象时,就是用一个模子,来制造一个实物
1. 理解self
看以下示例: # 定义一个类 class Animal: # 方法 def __init__(self, name): self.name = name def printName(self): print('名字为:%s'%self.name) # 定义一个函数 def myPrint(animal): animal.printName() dog1 = Animal('西西') myPrint(dog1) dog2 = Animal('北北') myPrint(dog2) |
总结
一、所谓的self,能够理解为本身
二、能够把self当作C++中类里面的this指针同样理解,就是对象自身的意思
三、某个对象调用其方法时,python解释器会把这个对象做为第一个参数传递给self,因此开发者只须要传递后面的参数便可
二、__init__()方法
想想:
在上一小节的demo中,咱们已经给BMW这个对象添加了2个属性,wheelNum(车的轮胎数量)以及color(车的颜色),试想若是再次建立一个对象的话,确定也须要进行添加属性,显然这样作很费事,那么有没有办法可以在建立对象的时候,就顺便把车这个对象的属性给设置呢?
<1>使用方式
def 类名: #初始化函数,用来完成一些默认的设定 def__init__():pass |
<2>__init__()方法的调用
# 定义汽车类 classCar: def__init__(self): self.wheelNum = 4 self.color = '蓝色' defmove(self): print('车在跑,目标:夏威夷') # 建立对象 BMW = Car() print('车的颜色为:%s'%BMW.color) print('车轮胎数量为:%d'%BMW.wheelNum) |
总结1
当建立Car对象后,在没有调用__init__()方法的前提下,BMW就默认拥有了2个属性wheelNum和color,缘由是__init__()方法是在建立对象后,就马上被默认调用了
想想:
既然在建立完对象后__init__()方法已经被默认的执行了,那么可否让对象在调用__init__()方法的时候传递一些参数呢?若是能够,那怎样传递呢?
# 定义汽车类 classCar: def__init__(self, newWheelNum, newColor): self.wheelNum = newWheelNum self.color = newColor def move(self): print('车在跑,目标:夏威夷') # 建立对象 BMW = Car(4, 'green') print('车的颜色为:%s'%BMW.color) print('车轮子数量为:%d'%BMW.wheelNum) |
总结2
一、__init__()方法,在建立一个对象时默认被调用,不须要手动调用
二、__init__(self)中,默认有1个参数名字为self,若是在建立对象时传递了2个实参,那么__init__(self)中出了self做为第一个形参外还须要2个形参,例如__init__(self,x,y)
三、__init__(self)中的self参数,不须要开发者传递,python解释器会自动把当前的对象引用传递进去
三、__new__方法
classA(object): def__init__(self): print("这是 init 方法") def__new__(cls): print("这是 new 方法") return object.__new__(cls) A() |
总结
一、__new__至少要有一个参数cls,表明要实例化的类,此参数在实例化时由Python解释器自动提供
二、__new__必需要有返回值,返回实例化出来的实例,这点在本身实现__new__时要特别注意,能够return父类__new__出来的实例,或者直接是object的__new__出来的实例
三、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上能够完成一些其它初始化的动做,__init__不须要返回值
四、咱们能够将类比做制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节
注意点
特殊方法名 |
默认的参数 |
功能描述 |
__init__() |
self |
已经建立了对象,初始化对象回调方法 |
__str__() |
self |
和toString |
__del__() |
self |
对象回收时候回调 |
__new__() |
cls |
对象建立的回调方法 |
四、__del__()方法
建立对象后,python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
当内存中构建一个对象数据的时候回调__init__()方法,
当内存中销毁(释放)一个对象时回调__del__()方法
import time classAnimal(object): # 初始化方法 # 建立完对象后会自动被调用 def__init__(self, name): print('__init__方法被调用') self.__name = name # 析构方法 # 当对象被删除时,会自动被调用 def__del__(self): print("__del__方法被调用") print("%s对象立刻被干掉了..."%self.__name) # 建立对象 dog = Animal("哈皮狗") # 删除对象 del dog cat = Animal("波斯猫") cat2 = cat cat3 = cat print("---立刻 删除cat对象") del cat print("---立刻 删除cat2对象") del cat2 print("---立刻 删除cat3对象") del cat3 print("程序2秒钟后结束") time.sleep(2) |
总结
一、当有1个变量保存了对象的引用时,此对象的引用计数就会加1
二、当使用del删除变量指向的对象时,若是对象的引用计数不是1,好比3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,若是再调用1次del,此时会真的把对象进行删除
五、"魔法"方法
1. 打印id()
若是把BMW使用print进行输出的话,会看到以下的信息
即看到的是建立出来的BMW对象在内存中的地址
二、定义__str__()方法
classCar: def__init__(self, newWheelNum, newColor): self.wheelNum = newWheelNum self.color = newColor def__str__(self): msg = "嘿,个人颜色是" + self.color + "我有" + str(self.wheelNum) + "个轮胎..." return msg def move(self): print('车在跑,目标:夏威夷') BMW = Car(4, "白色") print(BMW) |
总结
一、在python中方法名若是是__xxxx__()的,那么就有特殊的功能,所以叫作“魔法”方法
二、当使用print输出对象的时候,只要本身定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
若是有一个对象,当须要对其进行修改属性时,有2种方法
对象名.属性名 = 数据 ---->直接修改
对象名.方法名() ---->间接修改
为了更好的保存属性安全,即不能随意修改,通常的处理方式为
将属性定义为私有属性
添加一个能够调用的方法,供调用
classPeople(object): def__init__(self, name): self.__name = name defgetName(self): return self.__name defsetName(self, newName): if len(newName) >= 5: self.__name = newName else: print("error:名字长度须要大于或者等于5") xiaoming = People("bin") print(xiaoming.__name) |
classPeople(object): def__init__(self, name): self.__name = name defgetName(self): return self.__name defsetName(self, newName): if len(newName) >= 5: self.__name = newName else: print("error:名字长度须要大于或者等于5") xiaoming = People("bin") xiaoming.setName("wanger") print(xiaoming.getName()) xiaoming.setName("lisi") print(xiaoming.getName()) |
总结
一、Python中没有像C++中public和private这些关键字来区别公有属性和私有属性
二、它是以属性命名方式来区分,若是在属性名前面加了2个下划线'__',则代表该属性是私有属性,不然为公有属性(方法也是同样,方法名前面加了2个下划线的话表示该方法是私有的,不然为公有的)。
1. 继承的概念
在现实生活中,继承通常指的是子女继承父辈的财产,以下图
在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中即可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够,以下如所示:
2. 继承示例
# 定义一个父类,以下: class Cat(object): def __init__(self, name, color="白色"): self.name = name self.color = color def run(self): print("%s--在跑"%self.name) # 定义一个子类,继承Cat类,以下: classBosi(Cat): def setNewName(self, newName): self.name = newName def eat(self): print("%s--在吃"%self.name) bs = Bosi("印度猫") print('bs的名字为:%s'%bs.name) print('bs的颜色为:%s'%bs.color) bs.eat() bs.setNewName('波斯') bs.run() |
说明:
虽然子类没有定义__init__方法,可是父类有,因此在子类继承父类的时候这个方法就被继承了,因此只要建立Bosi的对象,就默认执行了那个继承过来的__init__方法
总结
一、子类在继承的时候,在定义类时,小括号()中为父类的名字
二、父类的属性、方法,会被继承给子类
3. 注意点
class Animal(object): def __init__(self, name='动物', color='白色'): self.__name = name self.color = color def __test(self): print(self.__name) print(self.color) def test(self): print(self.__name) print(self.color) class Dog(Animal): def dogTest1(self): #print(self.__name) #不能访问到父类的私有属性 print(self.color) def dogTest2(self): #self.__test() #不能访问父类中的私有方法 self.test() A = Animal() #print(A.__name) #程序出现异常,不能访问私有属性 print(A.color) #A.__test() #程序出现异常,不能访问私有方法 A.test() print("------分割线-----") D = Dog(name = "小花狗", color = "黄色") D.dogTest1() D.dogTest2()
|
一、私有的属性,不能经过对象直接访问,可是能够经过方法访问
二、私有的方法,不能经过对象直接访问
三、私有的属性、方法,不会被子类继承,也不能被访问
四、通常状况下,私有的属性、方法都是不对外公布的,每每用来作内部的事情,起到安全的做用
1. 多继承
从图中可以看出,所谓多继承,即子类有多个父类,而且具备它们的特征
Python中多继承的格式以下:
# 定义一个父类 classA: def printA(self): print('----A----') # 定义一个父类 classB: def printB(self): print('----B----') # 定义一个子类,继承自A、B class C(A,B): def printC(self): print('----C----') obj_C = C() obj_C.printA() obj_C.printB() |
运行结果:
----A----
----B----
说明:
一、python中是能够多继承的
二、父类中的方法、属性,子类会继承
注意点:
想想:
若是在上面的多继承例子中,若是父类A和父类B中,有一个同名的方法,那么经过子类去调用的时候,调用哪一个?
#coding=utf-8 class base(object): def test(self): print('----base test----') classA(base): def test(self): print('----A test----') # 定义一个父类 classB(base): def test(self): print('----B test----') # 定义一个子类,继承自A、B classC(A,B): pass obj_C = C() obj_C.test() print(C.__mro__) #能够查看C类的对象搜索方法时的前后顺序,C3算法获得一个元组 |
二、重写
<1>重写父类方法
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
#coding=utf-8 class Cat(object): def sayHello(self): print("halou-----1") class Bosi(Cat): def sayHello(self): print("halou-----2") bosi = Bosi() bosi.sayHello() |
<2> 调用父类的方法
#coding=utf-8 class Cat(object): def __init__(self,name): self.name = name self.color = 'yellow' class Bosi(Cat): def __init__(self,name): # 调用父类的__init__方法1(python2) #Cat.__init__(self,name) # 调用父类的__init__方法2 #super(Bosi,self).__init__(name) # 调用父类的__init__方法3 super().__init__(name) def getName(self): return self.name bosi = Bosi('xiaohua') print(bosi.name) print(bosi.color) |
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
所谓多态:定义时的类型和运行时的类型不同,此时就成为多态
Python伪代码实现Java或C#的多态
classF1(object): def show(self): print'F1.show' classS1(F1): def show(self): print'S1.show' classS2(F1): defshow(self): print'S2.show' # 因为在Java或C#中定义函数参数时,必须指定参数的类型# 为了让Func函数既能够执行S1对象的show方法,又能够执行S2对象的show方法,因此,定义了一个S1和S2类的父类# 而实际传入的参数是:S1对象和S2对象 def Func(F1 obj): """Func函数须要接收一个F1类型或者F1子类的类型""" print obj.show() s1_obj = S1() Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show s2_obj = S2() Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show |
Python “鸭子类型”
class F1(object): def show(self): print'F1.show' class S1(F1): def show(self): print'S1.show' class S2(F1): def show(self): print'S2.show' def Func(obj): print obj.show() s1_obj = S1() Func(s1_obj) s2_obj = S2() Func(s2_obj) |
在了解了类基本的东西以后,下面看一下python中这几个概念的区别
先来谈一下类属性和实例属性
在前面的例子中咱们接触到的就是实例属性(对象属性),顾名思义,类属性就是类对象所拥有的属性,它被全部类对象的实例对象所共有,在内存中只存在一个副本,这个和C++,java中类的静态成员变量有点相似。对于公有的类属性,在类外能够经过类对象和实例对象访问。
类属性:所属类,这个类下全部的对象均可以共享这个类属性。 至关于java中静态属性。
好比:
Class Person{
public static String name="abc"
}
一、类属性
class People(object): name = 'Tom'#公有的类属性 __age = 12#私有的类属性 p = People() print(p.name) #正确 print(People.name) #正确 print(p.__age) #错误,不能在类外经过实例对象访问私有的类属性 print(People.__age) #错误,不能在类外经过类对象访问私有的类属性 |
二、实例属性(对象属性)
classPeople(object): address = '山东'#类属性 def__init__(self): self.name = 'xiaowang'#实例属性 self.age = 20#实例属性 p = People() p.age =12#实例属性 print(p.address) #正确 print(p.name) #正确 print(p.age) #正确 print(People.address) #正确 print(People.name) #错误 print(People.age) #错误 |
三、经过实例(对象)去修改类属性
classPeople(object): country = 'china'#类属性 print(People.country) p = People() print(p.country) p.country = 'japan' print(p.country) #实例属性会屏蔽掉同名的类属性 print(People.country) del p.country #删除实例属性 print(p.country) |
总结
若是须要在类外修改类属性,必须经过类对象去引用而后进行修改。若是经过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,而且以后若是经过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
属性叫法 |
变量叫法 |
描述 |
类属性(私有和公有) |
类变量 |
全部对象共享同一份类属性。 |
实例属性(私/公) |
成员变量 |
每一个不一样对象,有不同值的实例属性 |
1. 类方法
是类对象所拥有的方法,须要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,通常以cls做为第一个参数(固然能够用其余名称的变量做为其第一个参数,可是大部分人都习惯以'cls'做为第一个参数的名字,就最好用'cls'了),可以经过实例对象和类对象去访问。
classPeople(object): country = 'china'#类方法,用classmethod来进行修饰 @classmethod def getCountry(cls): return cls.country p = People() print p.getCountry() #能够用过实例对象引用 print People.getCountry() #能够经过类对象引用 |
类方法还有一个用途就是能够对类属性进行修改:
classPeople(object): country = 'china'#类方法,用classmethod来进行修饰 @classmethod def getCountry(cls): return cls.country @classmethod Def setCountry(cls,country): cls.country = country p = People() print p.getCountry() #能够用过实例对象引用 print People.getCountry() #能够经过类对象引用 p.setCountry('japan') print p.getCountry() print People.getCountry()
|
结果显示在用类方法对类属性修改以后,经过类对象和实例对象访问都发生了改变
2. 静态方法
须要经过修饰器@staticmethod来进行修饰,静态方法不须要多定义参数
classPeople(object): country = 'china' @staticmethod#静态方法 Def getCountry(): return People.country print People.getCountry() |
总结
从类方法和实例方法以及静态方法的定义形式就能够看出来,类方法的第一个参数是类对象cls,那么经过cls引用的一定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么经过self引用的多是类属性、也有多是实例属性(这个须要具体分析),不过在存在相同名称的类属性和实例属性的状况下,实例属性优先级更高。静态方法中不须要额外定义参数,所以在静态方法中引用类属性的话,必须经过类对象来引用
方法类别 |
语法 |
描述 |
类方法 |
@classmethod |
第一个形参cls。默认传递 |
静态方法 |
@staticmethod |
没有默认传递的形参 |
对象方法(成员方法) |
def 方法名 |
第一个形参self ,默认传递 |
1. 单例是什么
举个常见的单例模式例子,咱们平常使用的电脑上都有一个回收站,在整个操做系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,并且回收站自行提供本身的实例。所以回收站是单例模式的应用。
确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象建立型模式。
2. 建立单例-保证只有1个对象
# 实例化一个单例 classSingleton(object): __instance = None def__new__(cls, age, name): #若是类数字可以__instance没有或者没有赋值 #那么就建立一个对象,而且赋值为这个对象的引用,保证下次调用这个方法时 #可以知道以前已经建立过对象了,这样就保证了只有1个对象 If not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance a = Singleton(18, "bin") b = Singleton(8, "bin") print(id(a)) print(id(b)) a.age = 19#给a指向的对象添加一个属性 b.print(b.age)#获取b指向的对象的age属性 |
运行结果:
In [12]: class Singleton(object): ...: __instance = None ...: ...: def__new__(cls, age, name): ...: if not cls.__instance: ...: cls.__instance = object.__new__(cls) ...: return cls.__instance ...: ...: a = Singleton(18, "bin") ...: b = Singleton(8, "bin") ...: ...: print(id(a)) ...: print(id(b)) ...: ...: a.age = 19 ...: print(b.age) ...: 4391023224439102322419 |
3. 建立单例时,只执行1次__init__方法
# 实例化一个单例 classSingleton(object): __instance = None __first_init = False def__new__(cls, age, name): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance def__init__(self, age, name): if not self.__first_init: self.age = age self.name = name Singleton.__first_init = True a = Singleton(18, "bin") b = Singleton(8, "bin") print(id(a)) print(id(b)) print(a.age) print(b.age)
|
工厂模式是咱们最经常使用的实例化对象模式了,是用工厂方法代替new操做的一种模式。虽然这样作,可能多作一些工做,但会给你系统带来更大的可扩展性和尽可能少的修改量(可维护性)。
1. 简单工厂模式
Simple Factory模式不是独立的设计模式,他是Factory Method模式的一种简单的、特殊的实现。他也被称为静态工厂模式,一般建立者的建立方法被设计为static方便调用。
一、静态的工厂类
二、用全局函数改写工厂类
2. 工厂方法模式
工厂方法模式去掉了简单工厂模式中工厂方法的静态方法,使得它能够被子类继承。对于python来讲,就是工厂类被具体工厂继承。这样在简单工厂模式里集中在工厂方法上的压力能够由工厂方法模式里不一样的工厂子类来分担。
抽象的工厂类提供了一个建立对象的方法,也叫做工厂方法。
1) 抽象工厂角色(Factory): 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。
2) 具体工厂角色(Stone_Axe_Factory,Steel_Axe_Factory):它含有和具体业务逻辑有关的代码。由应用程序调用以建立对应的具体产品的对象。
3) 抽象产品角色(Axe):它是具体产品继承的父类或者是实现的接口。在python中抽象产品通常为父类。
4) 具体产品角色(Stone_Axe,Steel_Axe):具体工厂角色所建立的对象就是此角色的实例。由一个具体类实现。
看以下示例:
print'-----test--1---' open('123.txt','r') print'-----test--2---' |
运行结果:
说明:
打开一个不存在的文件123.txt,当找不到123.txt 文件时,就会抛出给咱们一个IOError类型的错误,No such file or directory:123.txt (没有123.txt这样的文件或目录)
异常:
当Python检测到一个错误时,解释器就没法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"
<1>捕获异常 try...except...
看以下示例:
try: print('-----test--1---') open('123.txt','r') print('-----test--2---') except IOError: pass |
说明:
此程序看不到任何错误,由于用except 捕获到了IOError异常,并添加了处理的方法
pass 表示实现了相应的实现,但什么也不作;若是把pass改成print语句,那么就会输出其余信息
小总结:
把可能出现问题的代码,放在try中
把处理异常的代码,放在except中
<2> except捕获多个异常
看以下示例:
try: print num except IOError: print('产生错误了') |
想想:
上例程序,已经使用except来捕获异常了,为何还会看到错误的信息提示?
答:
except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,因此except没有生效
修改后的代码为:
try: print num except NameError: print('产生错误了') |
实际开发中,捕获多个异常的方式,以下:
#coding=utf-8 try: print('-----test--1---') open('123.txt','r') # 若是123.txt文件不存在,那么会产生 IOError 异常 print('-----test--2---') print(num)# 若是num变量没有定义,那么会产生 NameError 异常 except (IOError,NameError): #若是想经过一次except捕获到多个异常能够用一个元组的方式# errorMsg里会保存捕获到的错误信息 print(errorMsg) |
注意:
当捕获多个异常时,能够把要捕获的异常的名字,放到except 后,并使用元组的方式仅进行存储
<3>获取异常的信息描述
<4>捕获全部异常
<5> else
我们应该对else并不陌生,在if中,它的做用是当条件不知足时执行的实行;一样在try...except...中也是如此,即若是没有捕获到异常,那么就执行else中的事情
try: num = 100 print num except NameError as errorMsg: print('产生错误了:%s'%errorMsg) else: print('没有捕获到异常,真高兴') |
运行结果以下:
<6> try...finally...
try...finally...语句用来表达这样的状况:
在程序中,若是一个段代码必需要执行,即不管异常是否产生都要执行,那么此时就须要使用finally。 好比文件关闭,释放锁,把数据库链接返还给链接池等
demo:
import time try: f = open('test.txt') try: whileTrue: content = f.readline() if len(content) == 0: break time.sleep(2) print(content) except TypeError as ex: === catch(NullPointException ex) #若是在读取文件的过程当中,产生了异常,那么就会捕获到#好比 按下了 ctrl+c pass finally: f.close() print('关闭文件') except: print("没有这个文件") |
说明:
test.txt文件中每一行数据打印,可是我有意在每打印一行以前用time.sleep方法暂停2秒钟。这样作的缘由是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。
咱们能够观察到KeyboardInterrupt异常被触发,程序退出。可是在程序退出以前,finally从句仍然被执行,把文件关闭。
1. try嵌套中
import time try: f = open('test.txt') try: while True: content = f.readline() if len(content) == 0: break time.sleep(2) print(content) finally: f.close() print('关闭文件') except: print("没有这个文件") |
运行结果:
In [26]: import time ...: try: ...: f = open('test.txt') ...: try: ...: while True: ...: content = f.readline() ...: if len(content) == 0: ...: break ...: time.sleep(2) ...: print(content) ...: finally: ...: f.close() ...: print('关闭文件') ...: except: ...: print("没有这个文件") ...: finally: ...: print("最后的finally") ...: xxxxxxx--->这是test.txt文件中读取到信息 ^C关闭文件 没有这个文件 最后的finally |
2. 函数嵌套调用中
def test1(): print("----test1-1----") print(num) print("----test1-2----") def test2(): print("----test2-1----") test1() print("----test2-2----") def test3(): try: print("----test3-1----") test1() print("----test3-2----") except Exception as result: print("捕获到了异常,信息是:%s"%result) print("----test3-2----") test3() print("------华丽的分割线-----") test2() |
运行结果:
总结:
若是try嵌套,那么若是里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,而后进行处理,若是外边的try依然没有捕获到,那么再进行传递。。。
若是一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么若是函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,若是函数B有异常处理那么就会按照函数B的处理方式进行执行;若是函数B也没有异常处理,那么这个异常会继续传递,以此类推。。。若是全部的函数都没有处理,那么此时就会进行异常的默认处理,即一般见到的那样
注意观察上图中,当调用test3函数时,在test1函数内部产生了异常,此异常被传递到test3函数中完成了异常处理,而当异常处理完后,并无返回到函数test1中进行执行,而是在函数test3中继续执行
你能够用raise语句来引起一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类
下面是一个引起异常的例子:
class ShortInputException(Exception):'''自定义的异常类''' def__init__(self, length, atleast): #super().__init__() self.length = length self.atleast = atleast def main(): try: s = input('请输入 --> ') if len(s) < 3: # raise引起一个你定义的异常 raise ShortInputException(len(s), 3) except ShortInputException as result:#x这个变量被绑定到了错误的实例 print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast)) else: print('没有异常发生.') main() |
注意
以上程序中,关于代码#super().__init__()的说明
这一行代码,能够调用也能够不调用,建议调用,由于__init__方法每每是用来对建立完的对象进行初始化工做,若是在子类中重写了父类的__init__方法,即意味着父类中的不少初始化工做没有作,这样就不保证程序的稳定了,因此在之后的开发中,若是重写了父类的__init__方法,最好是先调用父类的这个方法,而后再添加本身的功能
classTest(object): def __init__(self, switch): self.switch = switch #开关 def calc(self, a, b): try: return a/b except Exception as result: if self.switch: print("捕获开启,已经捕获到了异常,信息以下:") print(result) else: #从新抛出这个异常,此时就不会被这个异常处理给捕获到,从而触发默认的异常处理 raise a = Test(True) a.calc(11,0) print("----------------------华丽的分割线----------------") a.switch = False a.calc(11,0) |
总结:
try:是异常捕获开始代码,try放在特别关心的那段代码前面
pass:若是这行代码出现了异常,那么后面的代码不会运行
pass2
pass3
except 异常的类型 as ex: 捕获某种类型的异常
except....多个except。按照顺序依次比对类型
else:没有异常时执行
finally:无论有没有异常都会执行
<1>Python中的模块
在Python中有一个概念叫作模块(module),这个和C语言中的头文件以及Java中的jar包很相似,好比在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。
说的通俗点:模块就比如是工具包,要想使用这个工具包中的工具(就比如函数),就须要导入这个模块
<2>import
在Python中用关键字import来引入某个模块,好比要引用模块math,就能够在文件最开始的地方用import math来引入。
形如:
import module1,mudule2...
当解释器遇到import语句,若是模块在当前的搜索路径就会被导入。
在调用math模块中的函数时,必须这样引用:
模块名.函数名
import math #这样会报错 print sqrt(2) #这样才能正确输出结果 print math.sqrt(2) |
有时候咱们只须要用到模块中的某个函数,只须要引入该函数便可,此时能够用下面方法实现:
<3>from…import
Python的from语句让你从模块中导入一个指定的部分到当前命名空间中
语法以下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块fib的fibonacci函数,使用以下语句:
from fib import fibonacci
注意:不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入
<4>from … import *
把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:
from modname import *
注意:这提供了一个简单的方法来导入一个模块中的全部项目。然而这种声明不应被过多地使用。
<5>定位模块
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
一、当前目录
二、若是不在当前目录,Python则搜索在shell变量PYTHONPATH下的每一个目录。
三、若是都找不到,Python会察看默认路径。UNIX下,默认路径通常为/usr/local/lib/python/
四、模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
<6>安装模块
conda create -n py2 python=2.7
conda install 模块
pip install 模块
pymysql
numpy
<1>定义本身的模块
在Python中,每一个Python文件均可以做为一个模块,模块的名字就是文件的名字。
好比有这样一个文件test.py,在test.py中定义了函数add
test.py
def add(a,b): return a+b
<2>调用本身定义的模块
那么在其余文件中就能够先import test,而后经过test.add(a,b)来调用了,固然也能够经过from test import add来引入
main.py
import test result = test.add(11,22) print(result)
<3>测试模块
在实际开中,当一个开发人员编写完一个模块后,为了让模块可以在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如:
test.py
def add(a,b): return a+b # 用来进行测试 ret = add(12,22) print('int test.py file,,,,12+22=%d'%ret)
若是此时,在其余py文件中引入了此文件的话,想一想看,测试的那段代码是否也会执行呢!
main.py
import test result = test.add(11,22) print(result)
至此,可发现test.py中的测试代码,应该是单独执行test.py文件时才应该执行的,不该该是其余的文件中引用而执行
为了解决这个问题,python在执行一个文件时有个变量__name__
<4>模块中的__all__
总结:
能够根据__name__变量的结果可以判断出,是直接执行的python脚本仍是被引入执行的,从而可以有选择性的执行测试代码
一、python中的包
1. 引入包
1.1 包就是一个目录
1.2 把多个py文件放到同一个文件夹下
1.3 使用import 文件夹.模块 的方式导入
python3能够导入包,python2不行。
1.4 使用from 文件夹 import 模块 的方式导入
python3能够导入包,python2不行。
1.5 在包的文件夹下建立__init__.py文件。
在python2中:有一个目录,而且目录下有一个__init__.py的文件。才叫包。
虽然文件内容没有,可是python2能够用了
有__init__.py文件在python3中没有有错。之后咱们都在包的目录下新建一个init文件。
1.6 在__init__.py文件中写入
from . import 模块1
from . import 模块2
那么能够使用import 文件夹 导入
1.7 也能够使用from 文件夹 import 模块 的方式导入
总结:
包将有联系的模块组织在一块儿,即放到同一个文件夹下,而且在这个文件夹建立一个名字为__init__.py 文件,那么这个文件夹就称之为包
有效避免模块名称冲突问题,让应用组织结构更加清晰
2. __init__.py文件有什么用
__init__.py 控制着包的导入行为
2.1 __init__.py为空
仅仅是把这个包导入,不会导入包中的模块
2.2 (了解)能够在__init__.py文件中编写内容
能够在这个文件中编写语句,当导入时,这些语句就会被执行
__init__.py文件
1.mymodule目录结构体以下:
.
├── setup.py
├── suba
│ ├── aa.py
│ ├── bb.py
│ └── __init__.py
└── subb
├── cc.py
├── dd.py
└── __init__.py
2.编辑setup.py文件
py_modules需指明所需包含的py文件
from distutils.core import setup setup(name="压缩包的名字", version="1.0", description="描述", author="做者", py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd']) |
3.构建模块
python setup.py build
4.生成发布压缩包
python setup.py sdist
1.安装的方式
一、找到模块的压缩包(拷贝到其余地方)
二、解压
三、进入文件夹
四、执行命令python setup.py install
注意:若是在install的时候,执行目录安装,能够使用python setup.py install --prefix=安装路径
conda create -n py2 python=2.7
2.模块的引入
在程序中,使用from import 便可完成对安装的模块使用
from 模块名 import 模块名或者*
一、给程序传参数
import sys print(sys.argv)
二、列表推导式
一、所谓的列表推导式,就是指的轻量级循环建立列表:
a = [i for i in range(1,10)]
b= [11 for i in range(1,10)]
[(1,1),(2,4),(3,9),(4,16).....]
二、在循环的过程当中使用if 来肯定 列表中元素的条件
a = [i for i in range(1,10) if i%2==0]
三、2个for循环
a=[(i,j) for i in range(1,5) for j in range(6,10)]
四、3个for循环
a= [(x,y,z) for x in range(2) for y in range(2) for z in range(2)]
三、set:集合类型
列表(list) |
a=[] |
前后顺序,有下标位[index],能够重复,可变类型 |
元组(tuple) |
a=() |
有前后顺序,有下标位,元素能够重复,不可变(只能查) |
字典(dict) |
a={key:value} |
没有前后顺序,没有下标,key不可重复,value能够,可变 |
集合(set) |
a=set() |
没有前后顺序,没有下标,不可重复,可变类型 |
注意:使用set,能够快速的完成对list中的元素去重复的功能