首页 > 编程语言 > 详细

python知识点总结

时间:2016-12-29 23:15:18      阅读:377      评论:0      收藏:0      [点我收藏+]

此知识要点,是根据学习廖雪峰phthon3.0教程总结的,所以结构基本和这个教程的结构相同。

背景知识

  1. python是什么?(1)python是一门编程语言,意味着可以用python编写程序,完成一定的功能;(2)python是一种脚本语言,这就是说,python程序需要在一个解释器中运行,这个解释器把程序翻译成计算机可执行的二进制代码,python的官方解释器叫做CPython.
  2. 安装python.所谓安装python,实际上主要是安装一个python解释器(CPython,以便使用该解释器执行python程序)和内置类库;除此之外,同时还会安装一个集成开发环境,这个集成开发环境叫做IDLE。
  3. python的代码库。python的代码库可以分为两类,一类是python内置的代码库,提供了包括网络/文件/GUI/数据库/文本处理等大量的功能,内置代码库在安装python的时候会同时安装;另一类是第三方代码库,在python上有大量的第三方代码库可供使用;
  4. 启动python.所谓启动python,实际上是启动python解释器(CPython),通过在命令行中输入python启动解释器。python解释器有两种模式,一种是交互式模式,在这种模式下,输入的代码在回车后会立即执行,并显示代码执行结果,在命令行中通过输入python进入交互式模式,输入exit()退出交互式模式;另一种是命令行模式,即在命令行中输入python [文件名.py],直接执行python程序。这里有一个问题,就是python可以用来编写web应用程序,web应用程序的基本功能是处理http请求,python程序是如何运行起来(或者说在上面的哪种模式下)处理http请求的呢?这是由web服务器和框架来启动python程序处理http请求的。所有用脚本语言编写的网站后台都是这种由框架启动的模式;
  5. python语言的输入和输出。python用variable = input()函数将用户输入保存在变量variable中,用print(‘hello‘, variable)函数产生输出;
  6. python程序需要保存为utf-8编码,在notepad++的Encoding菜单中选择Encode in UTF-8-BOM;

数据类型/变量/语句/运算符

  1. 强制缩进。(缩进的最佳实践是使用4个空格,而不使用Tab)这个理解起来比较容易,但是却说不上来;以#表示注释;Python区分大小写;当语句以:结束时,其后缩进的代码被视为代码块;
  2. python的简单数据类型:
    1. 整型:0x前缀表示十六进制,其他没有什么特别的;
    2. 浮点型:也可以用科学技术法表示,其他没有什么特别的;
    3. 字符型(字符串):(1)单引号或双引号扩起来的任意文本;(2)转义字符\,r‘‘表示其中的字符均不转义;(3)‘‘‘...‘‘‘(3个引号)用来表示多行内容;以上3点是定义字符串字面量的方式;(4)也可以使用构造函数str()来创建字符串;(5)字符串方法:
    4. 布尔型:用True、False表示布尔值(注意大小写);运算符:and or not;
    5. 一个特殊的空值None,空值在什么场合下有什么用?
  3. 运算符:
    1. 一元运算法:
  4. 变量。有两点注意即可:
    1. (1)python是一种动态语言,这就是说python中的变量没有固定的数据类型,可以给同一个变量赋任意数据类型的值;
    2. (2)变量和变量的值在内存中占有不同的位置,变量指向该变量的值,将一个字面值赋值给一个变量时,该变量将指向该值所在的内存,而将一个变量a赋值给另一个变量b时,被赋值的变量b将指向变量a的值所在的内存而非变量a所在的内存,这个行为无论是值类型还是引用类型,都是相同的。这样在改变b(指的是改变b本身,而非b所指向的内存,当然对于值类型来讲,只能改变b本身,没有改变b所指向的内存的机制,对于引用类型来讲,我们说的“改变b”实际上会有两种含义,一种是改变b本身,一种是改变b所指向的内存)的时候,也就是b会重新指向到一个新位置,这样是不会影响到a的。同时,如果我们说的改变b,指的是改变b指向的内存,而非b本身(只有对引用类型才可能这么做,对值类型不能这么做),那么a也会受到影响(跟C#达到的效果是相同的,只是对值类型的处理方式不同,C#在将一个值类型变量a赋值给b时,会赋值一份给b,这样达到a/b互不影响的目的,而python在赋值是不会赋值一份,但在修改b时,会让b指向一个新位置,从而也达到a/b互不影响的目的)。在python中值类型和引用类型的变量好像分别叫做不可变对象和可变对象。
    3. python中的特殊变量:
      1. __name__:当在命令行中运行python模块文件时,变量__name__被赋值为字符串‘__main__‘,而在其他地方导入python模块文件时,__name__不会被赋值,所以我们常用 if __name__ == ‘__main__‘来运行只想在命令行中执行时才运行的代码(如测试代码等);
      2. __author__:
      3. __doc__:
      变量的作用域:Python没有提供类似private、public的机制,以下只是习惯用法:
      1. 用_或者__作为前缀修饰变量、函数来表示private的含义;
    4. palceholder
  5. 常量。事实上,python中没有常量,也就是说python没有任何机制保证一个变量的值不被修改,但约定俗成的,用全部大写的变量名表示常量。
  6. python字符串和字符编码:
    1. 对于字符编码规则,我是这样理解的:字符编码规则是定义某种bit序列表示某个字符的规则,也就是使用一个特定的编码规则,可以将一个bit序列解释为一个字符。假如一个存储在磁盘上的文件,在磁盘上就是一个bit序列,这个bit序列表示的是什么含义,要结合该文件使用的字符编码来确定。一个工具软件要想知道这个bit序列的含义,需要1.知道这个文件所使用的字符编码规则;2.根据字符编码规则对这个bit序列进行解释,得到最终的含义。那么工具软件是怎样知道一个文件所使用的字符编码规则呢?好像是操作系统有一个默认的字符编码规则。另外一种可能是:这个bit序列其实是可以自解释的,也就是只能用某种字符编码规则对这个bit进行解释,才能得到有意义的内容(这个好像不太可能);
    2. python解释器默认好像是用UTF-8对源文件(即存储在磁盘上的bit序列)进行解释的,在遇到源文件中无法用UTF-8解释的内容时(比如在保存文件时用gb2312编码规则,那么源文件中的中文内容就不能用UTF-8解释),就会报错。但是可以在文件开头通过使用# coding=<encoding name>(如 # coding=gb2312)声明源文件使用的字符编码,这样也不会出错。但最好的方法还是把源文件以UTF-8保存,这样python解释器也按照UTF-8解释,这样简单不出错。
    3. 【Python中的字符串在内存中都是以Unicode(每个字符用两个字节表示)表示的,这样在将字符串内容通过网络传输或保存到磁盘中的时候,需要将Unicode的内容按照某种规则(如UTF-8)编码,得到一个字节序列,这个字节序列可用于传输或保存,这个通过encode(‘utf-8‘)转换。同理,python程序接受的字节序列,通过decode(‘uft-8‘)可以转化为python中的字符串。】这个其实我没有弄明白。
    4. 输出格式化的字符串。字符串的格式化是通过%运算符实现的,基本格式是:‘hello, 占位符‘ % (逗号分隔的实际内容)。这里“占位符”的格式比较重要,要记住,很多程序(像log4net等)都使用这个格式。%d:整数;%f:浮点数;%s:字符串;%x:十六机制整数。还可以在%后面用数字表示输出内容所占的长度(内容本身长度不足时用空格(默认)或0(需指定)补足),用%.数字f定义浮点数中小数点后的位数。
  7. list和tuple:
    1. list(和tuple)是什么?是python内置的数据类型。“数据类型”怎么会有append/insert/pop方法?这样看来,list好像又是类?或者这里说的“数据类型”、“类”等概念在静态语言和动态语言中的含义不同?
    2. list和tuple都表示元素的一种有序集合。区别在于tuple(叫做元组)一旦初始化后,其元素是不可修改的,“不可修改”的含义是:tuple类型的变量所包含的元素本身是不可修改的,但是这个变量所指向的值是可以修改的(参看上面3的说明)。
    3. 初始化list的语法是中括号[],如list1 = [ 1, ‘2‘, [ 3, ‘4‘ ] ],初始化tuple的语法是小括号(),如tuple1 = ( 1, ‘2‘, [ 3, ‘4‘ ] ),但使用索引值访问其中元素的方法都是中括号[],如list[0], tuple[0];向list中添加元素:list.append();list.insert(i,x);从list中移除元素:list.pop([i]);list.remove(x):移除list中所有等于x的元素;del list[i:j:k];另外一些对list的操作:len(list);max(list);min(list)
    4. python一个特殊的地方是,可以用负数作为索引值访问其中的元素,-1表示最后一个元素,依次类推;
    5. 定义只有一个元素的tuple,其语法是tuple = ( 1, ),而非tuple = (1),这是因为小括号()同时是运算符,后一种方式会使得变量tuple等于(1)的运算结果1,而非元组(1);
    6. range表示一个数字序列:其语法有两种:range(stop);range(start, stop, step);
  8. 条件判断的语法:
  9. 1 if <条件判断1>:
    2     <执行1>
    3 elif <条件判断2>:
    4     <执行2>
    5 elif <条件判断3>:
    6     <执行3>
    7 else:
    8     <执行4>

    需要注意的几点:(1)else if的语法是elif;(2)每个条件判断后面必须有个冒号:;(3)缩进的部分就是一个代码块;

  10. 循环的语法:
    1. for ... in ...循环:对于循环n次,则使用range(),如:for i in range(n);
    2. while循环;
    3. break;continue;
  11. dict:几点:(1)dict中的元素是一个key-value对,而不只是一个值;(2)dict的查找和插入速度比list快,这是因为value的内存位置是通过key值来计算的(这也是要求key必须是不可变对象的原因,否则计算出的位置不同,就不能找到value的正确位置);(3)dict的语法是使用花括号{key1:value1, key2:value2},元素用,分隔,key和value之间为:,以key为所以存取value,即dict[key]的语法。在dict变量中存入元素时,如果该变量中不含此key,则直接加入,否则会覆盖原有值,读取dict中的元素时,如果key不存在,则会报错,所以还可以使用dict.get(key[, default] )的方法获取元素的值,此时如果key不存在,则返回None或指定的默认值;(4)删除dict中的元素使用dict.pop(key)方法。
  12. set:几点:(1)set是一个不包含重复值的集合;(2)因为要判断其中的值是否相同,所以其中的值必须是不可变对象,除此之外,set和list更像;(3)创建set变量的语法特别在i.有一个set关键字;ii.需要将一个list作为输入集合,如下:s = set([1, 2, 3]);(4)set的add(element)和remove(element)方法;

函数

  1. 函数的定义:def 函数名( 逗号分隔的参数列表 ): 函数体
    1. 函数名:
    2. 参数列表:参数无数据类型,用逗号分隔。
    3. 返回值:在函数定义中,并不能定义返回值。但在函数体内部用return语句结束函数执行,return 语句可带有(多个)返回值,如果没有明确指定返回值,则函数的返回值为None,有多个返回值的,实际上是返回一个tuple。
  2. 调用函数:
    1. 在命令行模式下调用函数:
    2. 在交互式模式下调用函数:
  3. 再谈函数参数:
    1. 位置参数:就是常见的参数形式,没有特别的;
    2. 默认参数:(1)就是参数有一个默认值,在调用函数时,如果没有为有默认值的参数指定值,则该参数使用此默认值,如:函数power( x, n = 2 ),n即为有默认值的参数;(2)如果有多个有默认值的参数,那么调用此函数的时候,要么全部省略实际参数,要么依顺序提供实际参数,如果需要省略位于较前位置的实际参数值,那么为较后位置的参数提供实际参数时,要使用命名参数的形式,即 参数名 = 值 的形式;(3)默认参数的“坑”:
    3. 可变参数:是说函数参数的个数是不固定、可变的。定义可变参数的语法是在参数名前添加一个*,如:def calc( *numbers );实际上可变参数和类型为tuple的参数,效果是一样的,只是可变参数使得代码更简洁一些(可以认为是个语法糖),在调用函数的时候可以提供任意个参数;
    4. 关键字参数:也是函数参数的个数不规定、可变的,只是在调用函数时使用“参数名 = 值”的方式提供多个参数,这些“参数名 = 值”在函数内部将作为形式参数的元素加入到形式参数中(这个形式参数将转变为dict),定义关键字参数的语法是在形式参数名前添加两个*,如:def calc( **numbers )。
    5. 命名关键字参数:
    6. 在python中,调用函数的时候,不能传入未经定义的实参(这一点和javascript不一样,后者可以传入任意多的实参,如果在函数定义中无对应的形参,则多余参数将被忽略);
    7. python的函数参数整这么复杂,必要性是什么?

高级特性

  1. 切片(slice):切片是指获取list或tuple的一部分(或一个子集),不能对dict或set进行切片操作(因为其中的元素不是按顺序存储的)。切片的语法是:list[n1:n2:n3],其中n1为切片的起始索引,如果省略则为从0开始;n2为结束索引,若省略则为最后一个;n3则表示在起始索引和结束索引的范围内每n3个取一个元素,若省略,则每个元素都取。这个切片就像字符串的substring方法一样。
  2. 可迭代对象及迭代:迭代就是使用for循环依次访问可迭代对象中的每个元素。
    1. 什么是可迭代对象呢?
    2. 如何迭代list/dict/tuple/set/字符串:
    3. python的for循环非常特别,在for循环中可以引用多个变量,形如:for i, j, k in ...,这是要求in后的可迭代对象中也要有分别对应i,j,k多个变量的内容。
  3. 列表生成式list Comprehensions:专门用来生成一个(复杂的)list的机制。语法为:[ 对for中变量进行计算的表达式 for 变量列表 in 可迭代对象 if 对for中变量筛选的表达式],如:[ k + ‘ = ‘ + v for k, v in dict.items() if v % 2 == 0],这个语法真是足够灵活。
  4. 生成器generator:生成器可以认为是表示生成一个list的算法(而不像列表生成式那样直接生成了一个列表),list中的元素在需要时(比如访问这个元素时)才会生成(不需要时不生成,减少了内存占用,可表示无限集)。
    1. 创建生成器:方法一:把列表生成式语法中的[]替换为(),即创建了一个生成器;方法二:使用函数来创建生成器,但是用来创建生成器的函数,除了其中要有yield语句外,还是与一般的函数不同。不同之处在于在这个函数中,yield还需要放在一个循环语句中,这样,这个生成器才能生成多个列表元素。

函数式编程

所谓函数式编程,就是语言中的“函数”也是数据,可以被赋值给变量、作为另一个函数的参数等,总之是在使用数据的场合都可以使用“函数”。

  1. 高阶函数:就是可以将其他函数作为参数的函数。python内置的几个高阶函数有(这些高阶函数和C#中在集合上定义的扩展方法非常类似,它们的参数都是一个函数和一个可迭代对象,然后将函数作用于可迭代对象中的每个元素,产生结果):
    1. map(f, list):传入map的函数仅有一个参数,将此函数单独作用在可迭代对象的每个元素上(也就是依次用可迭代对象中的每个元素作为此函数的参数调用,需要注意的是,在函数中没有有关此元素在list中的位置信息,所以如果遇到需在函数中使用元素的位置信息的时候,不要使用高阶函数),其返回值是一个迭代器(可以转变为list而不直接返回list);
    2. reduce(f, list):传入reduce的函数有两个参数,达到的效果是:reduce(f, [x1, x2, x3, x4]) = f( f( f( x1, x2 ), x3 ), x4 ),reduce的返回结果,是函数的计算结果,而不再是一个迭代器或list;
    3. filter():传入filter的函数仅有一个参数,此函数依次作用于可迭代对象的每个元素时返回一个bool结果。整个filter的运算结果是一个迭代器,但排除了上面运算结果为false的元素;
    4. sorted():
  2. 函数作为返回值和闭包:大概了解是怎么回事,但是还是有些说不清楚,也很难应用起来。
  3. 匿名函数(在python中就是lambda表达式):语法是:lambda 逗号分隔的参数列表:表达式。匿名函数的返回值就是lambda表达式的值。python中,这里的“表达式”只是一个简单的表达式,不支持复杂的语句块;
  4. 装饰器:类似于OOP中的装饰器模式,Python直接从语言层面上支持此模式。python中的装饰器可以为一个函数临时增加一些功能。Python是通过下面的步骤实现此模式的:
    1. 定义一个参数为函数、返回值也是函数的函数,即装饰器函数,在返回的函数中调用传入的参数函数及添加其他功能,也就是返回的函数成为了参数函数的一个包装器;
    2. 在定义需要临时增加一些功能的函数时,在函数前使用“@装饰器函数名”语法修饰该函数,则在调用此函数时,会转为调用在装饰器函数中定义的包装函数,从而达到临时增加功能的目的;
    3. 实际上包装器函数和原函数的一些属性还是不同的,如__name__属性等,但python通过functools模块中的wraps函数可以将原函数的属性复制给包装器函数,所以在装饰器函数中要求这么一句@functools.wrap(原函数名);
    4. 总结起来,装饰器函数有这么几个特征(1)其参数为一个函数;(2)返回值也是一个函数;(3)在返回值函数中调用参数函数并添加其他功能,达到为参数函数临时增加功能的目的;(4)通过“@装饰器函数名”的方式修饰其他函数,从而为该函数增加装饰器中增加的临时功能;(5)装饰器函数中要有这样一个语句:@functools.wrap(原函数名),用于将原函数属性复制给包装器函数;这也太笨拙了吧?
  5. 偏函数:就是通过为一个函数中的某些参数指定默认值,从而形成一个新函数,这个新函数成为原函数的偏函数。python是通过functools模块中的partial方法做到这一点的,这个作用不太大,等到用到的时候在详细查看其语法吧。

模块

模块是Python中组织源代码的一种机制,一个.py文件就是一个模块,模块名是该.py文件所在的文件夹名与文件的组合,用.分隔,即“文件夹名.文件名”;

用文件夹来组织模块的方式,称为“包(Package)”。可以作为包的文件夹中必须包含一个__init__.py文件(这个__init__.py文件本身可以为空,也可以包含代码,它本身也是一个模块,但它的模块名不是__init__,而是它所在文件夹的名称),否则该文件夹只是一个普通的文件夹而非“包”(“包”类似C#中命名空间的机制)。

使用内置模块

只要安装了Python,内置模块就可以使用。使用模块的第一步是导入模块,语法为import 模块名,如:

import sys

导入模块后,将相当于定义了一个与模块同名的变量sys,使用该变量来引用该模块,如sys.argv,就是引用模块sys中定义的变量argv。

使用第三方模块

使用第三方模块之前,需要首先进行安装。在Python中,是通过包管理工具pip完成第三方模块管理的。

pip命令:

pip search param
pip install param
pip uninstall param
pip list

面向对象编程

面向对象编程的内容:类、对象、类和对象的成员、封装、继承、多态;类及其成员的可访问性public/private/protected;构造函数

1 class Student(object):
2 
3     def __init__(self, name, score):
4         self.name = name
5         self.score = score

创建类的实例:
student = Student()
  1. 定义类的语法:class 类名( 基类 ):,object是所有类的基类,如果上面的定义中省略了基类,则默认从object继承,如:class Student( object ):;
  2. 构造函数及创建对象:如果定义类时,未显式定义类的构造函数,则类默认拥有一个无参数的构造函数,如果显示定义了构造函数,则此默认构造函数就不在存在。类的构造函数名必须是__init__。创建对象时,传入的参数必须与类的构造函数的参数匹配(self参数除外);
  3. 类和对象的属性:
    1. 类属性:(1);(2)可以为类动态添加属性,如:Student.score = 90,这样的属性相当于C#的静态成员,为类动态添加的属性会立即体现在类的对象中;(3)以__开头的属性是private,不能直接访问(这不是约定,而是python的限制),如果需要访问,则需要定义对应的get/set方法;(4)类似__xxx__的属性都是类的特殊变量,但不是private的;
    2. 对象属性:可以为对象动态添加属性,如student1.score = 80;如果对象的属性与类的属性重名,则对象的属性覆盖类的属性;这个可能和javascript的属性访问机制一样,即从底层开始,找到后即不在继续向上层查找;
    3. 类的方法:(1)与普通函数的区别在于,类的方法,其第一个参数永远是self(语法是:def methodname(self)),但在调用时不必传入该参数;(2)也可以为类动态添加方法,先定义一个第一个参数是self的方法,动态添加方法的语法是:类名.方法名 = MethodType( 方法名, 类名 )
  4. 继承和多态:继承和多态总体上来讲和C#一样,区别在于:python中在子类中定义的与父类同名的方法,自动全部是多态的(C#有覆盖和复写的区别,python没有?),python中有无类似abstract机制?
  5. 获取对象信息,使用以下函数:
    1. type():用来判断对象的类型。python的设计不严谨,这个type()函数就是个很好的例子。type()函数返回值的类型是什么呢?是类。那是什么类呢?他可以和int/str/bool/bytes(对于基本数据类型)、类名(对于一般类)、types模块中定义的常量(如:FunctionType等)比较。是不是太灵活了?
    2. isinstance():判断某个变量是否为某种或某几种类型,返回值为True或者False;
    3. dir():获取一个对象所有的属性和方法,返回值是一个包含对象所有属性和方法名的list;
    4. hasattr()/getattr()/setattr():用于判断一个属性/方法名(字符串表示)是否为一个对象的属性/方法。
  6. 再谈动态添加属性、方法和类的__slots__属性:
  7. @property:

多进程和多线程

“多进程/多线程”和“异步”、“并行”的概念有什么区别?

 

 

1.重要的是要知道,哪些功能在哪些模块中;

2.Python的文档很难看懂,也许是还没有找到看python文档的正确方法;

 

python知识点总结

原文:http://www.cnblogs.com/leegsh/p/4775800.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!