-
python简介
-
Q:能不能像.exe文件那样直接运行.py文件呢?
-
:在Windows上是不行的,但是,在Mac和Linux上是可以的,方法是在.py文件的第一行加上:
#!/usr/bin/env python,然后通过命令$ chmod a+x hello.py -
数据类型和变量
- Python程序是大小写敏感的.
- 当语句以冒号
:结尾时,缩进的语句视为代码块。 - Python还允许用
r' '表示' '内部的字符串默认不转义 - **空值:**用none表示,None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
- =:是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量
- **动态语言:**这种变量本身类型不固定的语言称之为动态语言
- **静态语言:**静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。(如java)
- 常量:就是不能变的变量,在Python中,通常用全部大写的变量名表示常量
-
字符串和编码
- ASCII →Unicode(解决所有语言统一到一套编码中,不会有乱码问题)→UTF-8 (可变长字符编码,解决空间浪费的问题)
- 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码
- Python诞生早于unicode,所有Python内部只支持ASCII编码。
- Python后来添加了对unicode的支持,用
u'...' - 字符串'xxx'虽然是ASCII编码,但也可以看成是UTF-8编码,而u'xxx'则只能是Unicode编码
- 把u'xxx'转换为UTF-8编码的'xxx'用encode('utf-8')方法; 反向则用decode
- 由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
#!/usr/bin/env python(linux) # -*- coding: utf-8 -*-(windows)- **格式化字符:**对整数来说,在%和d之间加上的数值表示需要格式化的这个整数占的位数,而再加入一个0就是说要在没有数的空位上补零
- 字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%
- 在Python 3.x版本中,把'xxx'和u'xxx'统一成Unicode编码,即写不写前缀u都是一样的,而以字节形式表示的字符串则必须加上b前缀:b'xxx'。
-
使用list和tuple
- list []: 列表(内置的数据结构)。 list是一个可变的有序表,用索引来访问list中每一个位置的元素,记得索引是从0开始的,最好一个索引是-1,可以删除pop,增加insert,追加append
- tuple ():元组(另一种有序列表),但是tuple一旦初始化就不能修改
-
条件判断:
- if语句:if判断为
True则执行缩进的代码块 - if...else语句:if判断为
FALSE则直接跳到else的代码块 - if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else
- if语句:if判断为
-
循环: (python有2种循环)
- for X in...循环,依次把list,tuple中的元素代入X,然后执行缩进语句。
- while循环:只要条件满足,就不断循环,条件不满足时退出循环。
- break(必须配合if使用):提前退出循环
- continue(必须配合if使用):在循环中,通过continue语句,跳过当前循环,直接进入下一次循环。
- range()函数:生成整数序列,如:range(5)是从0开始小于5的整数。
- list()函数:可以转换为list。用于将元组转换为列表 如:list(range(5))→ [0, 1, 2, 3, 4]
-
dict {}
- dict(字典)使用键-值(key-value)存储,具有极快的查找速度。
- 把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
- 多次对一个key放入value,后面的值会把前面的值冲掉
- 避免key不存在的错误,两种方法:①
in判读 ②通过dict提供的get方法(key不存在,可以返回none。返回none,Python交互命令行不显示结果) - 删除key,用
pop(key)方法 - dict相对list是用空间换取时间(内存占用多,查找时间少)
- 需要牢记的第一条就是dict的key必须是不可变对象
- 不可变对象 str,none都是不可变对象
- set([])
- set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
- 要创建一个set,需要提供一个list作为输入集合
- 重复元素在set中自动被过滤
- 通过add(key)方法可以添加元素到set中
- 通过remove(key)方法可以删除元素
- set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作
- set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象
- 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
-
调用函数 内建函数文档
- 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
-
定义函数
- 函数内执行到return,函数执行完毕,并返回结果。如果没有return,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return。
-
如果想定义一个什么事也不做的空函数,可以用pass语句,pass可以用来作为占位符(比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。)
-
Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
-
函数的参数
- 默认参数默认参数可以简化函数的调用。(默认参数必须指向不变对象)注意:①必选参数在前,默认参数在后②多个参数时,变化大放前,变化小的放后,变化小的可做默认参数。
- 可变参数传入的参数个数是可变的。定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个号。在函数内部,参数接收到的是一个tuple。(**Python允许你在list或tuple前面加一个号,把list或tuple的元素变成可变参数传进去**)
- 关键字参数关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。前面加两颗** 关键字参数有什么用?它可以扩展函数的功能。
- 参数组合 参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
- 总结(需要反复看)
-
递归函数:
- 如果一个函数在内部调用自身本身,这个函数就是递归函数
- 理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
- 尾递归解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。(尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。)
-
- 切片 看来range()产生的是list,对字符串也可以进行切片。
- 迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。
- Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
- 当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型
- 默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.itervalues(),如果要同时迭代key和value,可以用for k, v in d.iteritems()。
- 那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断
- Python内置的enumerate函数可以把一个list变成索引-元素对
- 列表生成式列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
- 而列表生成式则可以用一行语句代替循环生成上面的list
- 生成器 如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator),generator保存的是算法。generator也是可迭代对象
- 产生生成器的方法:①只要把一个列表生成式的[]改成(),就创建了一个generator
- ②generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
-
函数式编程
- 高阶函数既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数.编写高阶函数,就是让函数的参数能够接收别的函数。
- map/reduce lambda函数的用法?
- 装饰器这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数。???
- 偏函数 Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。所以,简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
-
模块 + 模块:我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)(使用模块最大的好处是大大提高了代码的可维护性。) + 包(Package):为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包。(只要包名不一样,一样的模块名也不冲突) + 请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。 + “使用模块” :Python解释器把一个特殊变量__name_置为_main(可是为什么在解释器中就可以置换呢?) + sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称 + 作用域 在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过
_前缀来实现的。 + 正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等; + 类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途. + 类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,_abc等; + 外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。(这也是一种非常有用的代码封装和抽象的方法) + 安装第三方模块在Python中,安装第三方模块,是通过setuptools这个工具完成的。Python有两个封装了setuptools的包管理工具:easy_install和pip。目前官方推荐使用pip。 + 现在安装的版本已经落后了,用python -m pip install --upgrade pip 进行更新pip + **使用_future** 比如2.x里的字符串用'xxx'表示str,Unicode字符串用u'xxx'表示unicode,而在3.x中,所有字符串都被视为unicode,因此,写u'xxx'和'xxx'是完全一致的,而在2.x中以'xxx'表示的str就必须写成b'xxx',以此表示“二进制字符串”。 + Python提供了__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性。 -
面向对象编程 + 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。 + 在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的**类(Class)**的概念。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念. + **实例(instance)**而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student: + **对象的方法(Method)**给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法(Method)(方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;) + 所以,面向对象的设计思想是抽象出Class,根据Class创建Instance。 + 注意到_init__方法的第一个参数永远是self,表示创建的实例本身,因此,在_init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。 + 和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数和关键字参数。 + 访问限制 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问. + 在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量 + 继承和多态 + 继承有什么好处?最大的好处是子类获得了父类的全部功能。 + 多态当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。 + 在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行 + **“开闭”原则:**对扩展开放,对修改封闭
{{ message }}
