首页 > 技术文章 > 【01】Python基础入门 (全)

djcoder 2019-05-30 18:25 原文

一、字符串

1. 字符串切片  

  切片:

name=“abcdef” name[2:5]=“cde”

  跳取:

name=“abcdef” name[2:-1:2]=“ce”

  逆序:

name=“abcdef” name[-1::-1]=“fedcba”

2.字符串的常见操作

  find:检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则返回-1。

mystr.find(str, start=0,end=len(mystr))

  index:跟find()方法一样,只不过如果str不在 mystr中会报一个异常。

mystr.index(str, start=0,end=len(mystr))

  count:返回 str在start和end之间 在mystr里面出现的次数。

mystr.count(str, start=0, end=len(mystr))

  replace:把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次。

mystr.replace(str1, str2,  mystr.count(str1))

  split:以str 为分隔符切片mystr,如果 maxsplit有指定,则仅分隔 maxsplit 个子字符串。

mystr.split(str=" ", 2)

  capitalize:把字符串的第一个字符大写。

mystr.capitalize()

  title:把字符串的每个单词首字母大写。

mystr.title()

  startswith:检查字符串是否是以obj开头, 是则返回 True,否则返回 False。

mystr.startswith(obj)

  endswith:检查字符串是否以obj结束,如果是返回True,否则返回 False。

mystr.endswith(obj)

  lower:转换 mystr 中所有大写字符为小写。

mystr.lower()

  upper:转换 mystr 中的小写字母为大写。

mystr.upper()

  ljust:返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串。

mystr.ljust(width)

  rjust:返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串。

mystr.rjust(width)

  center:返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。

mystr.center(width)

  lstrip:删除 mystr 左边的空白字符。

mystr.lstrip()

  rstrip:删除 mystr 字符串末尾的空白字符。

mystr.rstrip()

  strip:删除mystr字符串两端的空白字符。

mystr.strip()

  rfind:类似于 find()函数,不过是从右边开始查找。

mystr.rfind(str, start=0,end=len(mystr))

  rindex:类似于 index(),不过是从右边开始。

mystr.rindex( str, start=0,end=len(mystr))

  partition:把mystr以str分割成三部分,str前,str和str后。

mystr.partition(str)

  rpartition:类似于 partition()函数,不过是从右边开始。

mystr.rpartition(str)

  splitlines:按照行分隔,返回一个包含各行作为元素的列表。

mystr.splitlines()

  isalpha:如果 mystr 所有字符都是字母则返回 True,否则返回 False。

mystr.isalpha()

  isdigit:如果 mystr 只包含数字则返回 True 否则返回 False。

mystr.isdigit()

  isalnum:如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False。

mystr.isalnum()

  isspace:如果 mystr 中只包含空格,则返回 True,否则返回 False。

mystr.isspace()

  join:mystr 中每个字符后面插入str,构造出一个新的字符串。

mystr.join(str)

3.字符串常见问题

  ①字符串是不可变类型,是不能直接就改的,那么就先要将其转化为列表,然后在循环中找到该元素,通过列表进行更改。

for i,string in enumerate(list):
    if string == "love":
        list[i]="automn"

二、列表

1.列表的相关操作

  (1)添加元素("增"append, extend, insert)

          list.append(obj): 通过append可以向列表添加元素。

          list.extend(obj): 通过extend可以将另一个集合中的元素逐一添加到列表中。

          list.insert(index,obj):在指定位置index前插入元素object。

  (2)删除元素("删"del, pop, remove)

          del:根据下标进行删除,del list[i]。

          pop:删除最后一个元素,list.pop()。

          remove:根据元素的值进行删除,list.remove("obj")。

  (3)修改元素("改OBJ[i] = "X"")

          修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改。

  (4)查找元素("查"in, not in, index, count)

          in(存在),如果存在那么结果为true,否则为false。

          not in(不存在),如果不存在那么结果为true,否则false。

          index和count与字符串中的用法相同。

  (5)排序(list.sort(cmp = None,key = None,reverse = False))

         sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小,list.sort() | list.sort(reverse=True)。

          reverse方法是将list逆置,list.reverse()。

          reverse=True就是从大到小,key=len就是长度划分,reverse=True就是列表倒序。

 2.列表与字符串对比及转化

  (1)列表和字符串的相同点

          索引,切片,合并

  (2)列表和字符串的不同点

          在字符串中,每个元素只能是字符,在列表中,元素可以任意类型

          列表可以改变,字符串不能改变

  (3)列表和字符串的转化

          mystr.split("  "):可以使字符串以空格方式隔开并以列表存放

          ".".join(list):列表可以用"."来连接列表的元素

 3.列表常见问题  

  漏删元素。

num = [11,22,33,44,55,66]
    for i in num:
        if i == 33 or i == 44:
            num.remove(i)

  解释:此时的结果是num = [11,22,44,55,66],即出现了漏删的情况,因为删完33时,44往前挪一位,即跳过了它。

  解决:要想避免漏删就要在这个外面加上一个while True死循环,也可以把要删的全部组合成另一个列表b,然后一个for循环,for i in b: num.remove(b)。

三、字典

1.字典的相关操作

  (1)添加元素(变量名['键'] = 数据)

          这个键在字典中,不存在,那么就会新增这个元素。

  (2)删除元素(del,clear())

          del 变量名["键"]:删除指定元素

          del 变量名:删除整个字典

          变量名.clear():删除整个字典

  (3)修改元素(字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改)

          变量名['键'] = 数据

 2.字典的常见操作

  len:测量字典中,键值对的个数。

len(dict)

  keys:返回一个包含字典所有KEY的列表。

dict.keys()

  values:返回一个包含字典所有value的列表。          

dict.values()

  items:返回一个包含所有 (键,值) 元组的列表。       

dict.items()

  has_key: 如果key在字典中,返回True,否则返回False。

dict.has_key(key)

  get: 获得某个键的值。      

dict.get(key)              
dict["key"]  # 也可获取值但如果键不存在,就会异常,而dict.get()只返回一个空

  setdefault:如果有这个键就会返回它的值,没有的话就创建这个键值对。

dict.setdefault(key)

  items/iteritems,key/iterkeys,values/itervalues

# 能够得到字典的列表,元素是键和值的元组
infor.items()  

# 是一个"dictionary-itemiterator"类型,这种迭代器类型,必须用list转换一下,才能看到里面的真面目
infor.iteritems()

3.字典常见问题

  ①dict = {} ,并不是真正意义的清空,它只是指向了另一个对象。

  ②不能重复删除同一个键,即删除一个没有键会发生异常。

  ③可变类型在字典中不能当作键值 (原因是它可变,故地址不确定)。

四、元组和集合

1.列表和元组

  基本没什么区别,都能存多个值,唯一的区别就是元组不让增删改(只读)。

2.元组的内置函数

  ①cmp(tuple1,tuple2):比较两个元组元素。

  ②len(tuple):计算元组元素个数。

  ③max(tuple):返回元组中元素最大值。

  ④min(tuple):返回元组中元素最小值。

  ⑤tuple(seq):将列表转换为元组。

3.集合的去重

  可以用set()来去重复,也可以set = {},但并不推荐,因为容易与字典相混淆。

4.集合常用操作

  (1)增:set.add("jack")  # 新添加元素

          set.update("huang")   #从另一个集合合并到一起。

  (2)删:pop,remove,discard,clear

          set.pop()不能有参数,且是随机删除,当删除到集合为空如果还继续删除则发生异常。

          set.remove("obj") 删除指定的元素,没有则发生异常。

          set.discard("obj") obj是set里的元素就删除,不是就不做,不发生异常。

          set.clear()清空整个集合。

 5.元素和集合的关系

  "obj" in set ,元素在集合内就返回True,没有就返回False。

 6. 集合与集合关系

  ①相等与不等:a==b,a!=b ,正确就返回True,错误就返回False。

  ②子集:c<a  ,True,c是a的子集,c.issubset(a)判断c是否是a的子集。

  ③并集:a.union(b) ,把a集合和b集合并起来。

  ④交集:a.intersection(b) ,把a集合和b集合交起来。

五、函数

1.函数的定义

  把具有一个独立功能的代码块当作一个整体,这个整体就是函数。

2.函数的目的

  使程序变的更加模块化。

3.实参

  当调用一个函数的时候,传递的值叫实参(实实在在传递的)。

4.形参

  用来接收的叫形参,过程希望调用时,传递该值。

5.局部变量

  在一个函数里能用,出了这个函数哪都用不了,这样的变量称为局部变量。

6.全局变量

  定义在函数外面的变量,在整个代码中都可使用。

7.修改全局变量的值

  在修改语句前加上global变量名,这是对一个全局变量的声明,但是列表和字典可加可不加。

8.规避命名相同

  全局变量和局部变量名字相同,在函数里会使用局部变量,默认是定义,为了规避全局变量和局部变量名字相同,定义全局变量的时候g_a=100。

9. 函数的缺省参数

  调用函数时,缺省参数的值如果没有传入,则被认为是默认值,带有默认值的参数一定要位于参数列表的最后面,如print默认是换行,有了end就是就不换行。

10.函数返回多值

  如果需要用一个函数返回多个值,但是在函数中只要执行到一个return,就返回结束,所以可以通过列表或元组来封装变量的值。

11.不定长参数

  如test(a,b,c=33, *args, **kwargs)形参,如果实参在传递的时候有变量名的赋值就是字典的形式存储在kwargs中,没有变量名的就是args里。

12.命名空间

  表示标识符的可见范围,它是对作用域的特殊抽象,它包含处于该作用域的标识符。

13.匿名函数的应用场合  

  ①自己定义函数:函数作为参数传递,lambda x,y:x+y。

  ②作为内置函数的参数:lam = lambda x:x+3    ret = lam(3)。

  ③如果列表里是字典:infors.sort(key = lambdax:x[&lsquo;name&rsquo;])(按name的首字母来排序)。

六、作用域

1.命名空间

  变量命名的范围(变量起作用的范围)。

2.LEGB规则

  Python 使用 LEGB 的顺序来查找一个符号对应的对象,即 locals -> enclosing function -> globals -> builtins 。 

  ①locals,当前所在命名空间(如函数、模块),函数的参数也属于命名空间内的变量。

  ②enclosing,外部嵌套函数的命名空间(闭包中常见)。

  ③globals,全局变量,函数定义所在模块的命名空间。

  ④builtins,内建模块的命名空间。

  在Python中,有一个内建模块,该模块中有一些常用函数,在Python启动后,且没有执行程序员所写的任何代码前,Python会首先加载该内建函数到内存。另外,该内建模块中的功能可以直接使用,不用在其前添加内建模块前缀,其原因是对函数、变量、类等标识符的查找是按LEGB法则,其中B即代表内建模块。

  比如:内建模块中有一个abs()函数,其功能求绝对值,如abs(-20)将返回20。

七、面向对象

1.面向对象和面向过程的区别

  ①面向过程:根据业务逻辑从上到下写代码。

  ②面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程(能让程序更加简单,更加紧凑面向对象和面向过程都是解决问题的一种思路而已)。

2.类和对象的关系

  ①对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念-类。

  ②类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在,一个类可以找到多个对象。某一个具体事物的存在,在现实世界中可以是看得见摸得着的,可以是直接使用的。

3.新式类和旧式类

  ①新式类:广度优先,从最接近的上一个类开始,依次往上寻找相应的继承属性。

  ②旧式类:深度优先,从最开始的类开始,依次往下寻找相应的继承属性。

4.类里面的方法和函数的区别

  类里的方法和函数外观很相似,都采用def hanshu():,但是类的方法里必须要有一个形参,可以是self,可以是a,b,c,d等等,但是在调用的时候,实参里不能传递任何值。

5.类的内置方法

  ①__init__方法(给对象添加特定的属性)

  ②__str__方法(返回调用对象的信息)

  ③__del__方法(当删除一个对象时,Python解释器会默认调用这个方法,释放内存)

  ④__new__方法(__new__必须要有返回值,返回实例化出来的实例,至少要有一个参数cls)

6.测量对象的引用个数

  导入sys模块,采用sys模块里的sys.getrefcount(对象),就会返回一个值,但是这个值比实际对象多1。

7.单例模式

  确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建模式,__instance = None,没有这个实例就创建。

8.内置命名空间,全局命名空间,本地命名空间

  ①内置命名空间:python运行起来,它们就存在了,内置函数的命名空间都属于内置命名空间。

  ②全局命名空间:每个模块创建它自己所拥有的全部命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同步相互干扰。

  ③本地命名空间:模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间,如果函数返回了结果或者抛出异常,则本地命名空间也结束了。

9.公有属性和私有属性

  ①公有属性:可以被对象和方法直接访问。

  ②私有属性:不能通过对象直接访问,但能通过方法访问。 

10. 类属性和实例属性

  (1)类属性

          类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,只存在一个副本。

          类属性,可以被所有类对象和实例对象访问,就好比是实例对象的共享属性称为类属性。

          在给类添加属性的时候,该属性被放入类对象的__dict__魔法字典的键值对中。

  (2)实例属性

          不可变类型:实例属性不能左右类属性,但类属性能影响实例属性。

          可变类型:实例属性和类属性之间可以互相改变。

         在给实例添加属性的时候,该属性被放入实例对象的__dict__魔法字典的键值对中。

11. 类方法和静态方法

  (1)类方法

          是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法。

          第一个参数必须是类对象,一般以cls作为第一个参数。

          可以对类属性进行修改,它不能访问实例属性。

          可以被类对象和实例对象访问。

  (2)静态方法

          要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数。

          它无法访问实例变量,类,和实例属性。

          可以被类对象和实例对象调用。

12.公有方法和私有方法

  ①公有方法:调用就可以执行,还可以调用私有方法。

  ②私有方法:一般表示是比较重要的方法,且一般需要获得一定条件才可调用,称为是私有方法。

13.继承与多继承

  ①被继承者称为父类 (基类),继承者称为子类 (派生类)。

  ②在继承的过程中,父类的私有属性,私有方法,也就是由双下划线__test():组成的不能继承。

  ③继承的意义与好处

    可以实现代码复用,但也不是全部复用,可能不用。

    实现属性和方法继承。

  ④只有父类的公有方法能访问父类的私有属性和私有方法,子类的公有方法没有访问权限。 

14.重写与调用

  ①重写就是把方法与父类同样的定义一遍。

  ②如果发现在继承的时候,父类的方法的名字就是想要的名字,但不是想要的功能的时候,那么这个时候就可以去重写。

  ③调用被重写:类名.方法(self),super().方法()。

  ④每次在继承的时候,要把__init__()方法继承下来。

15.多态

  是指面向对象程序执行时,相同的信息可能会送给多个不同的类别对象,系统可根据对象所属类别,引发对应类别方法而有不同的行为。 

16.面向对象常见问题

  (1)逻辑属性要用方法来赋值

          在给对象设置属性的时候,直接赋予的话,可能某种情况下会发生不合逻辑的情况,如dog.age = -10,如果用方法来赋值,这样可以引入判断,如if new_age >0:  self.age = new_age

  (2)解耦合

          如果类与类之间的耦合性过强,也就是一个类改变,另一个类也需要改变,此时可以定义一个函数,把其中一个类的方法形参传递到这个函数中,再在这个函数里返回到类中,这种思维叫做解耦。

  (3)工厂方法模式

          工厂方法模式让类的实例化推迟到子类,抽象的CarStore提供了一个创建对象的方法createCar,也叫作工厂方法。   

八、异常

1.异常的介绍    

  解释器无法继续执行,出现了一些错误的提示,这就是所谓"异常">。

2.捕获异常

  ①把可能出现问题的代码,放在try中。

  ②把处理异常的代码,放在except中。

  ③当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式进行存储。

3.异常的传递

  如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,就会传递到函数B中,以此类推。 

4.自定义异常

  用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类,抛出异常直接默认raise 。

5.assert断言语句

  assret是语句等价于布尔真的判断,发生异常就意味着表达式为假,当条件不满需就会报错。

九、模块

1.模块的介绍

  模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块。

2.制作模块

  为了让我们自己写的模块被python解释器知道,需要用sys.path.append("路径"),但这种情况下,比如在交互模式下,如果关闭了,再开启,还要重新告知。

  常用方法:设置PYTHONPATH环境变量。

vim /etc/profile
export PATH = /home/jack/python:$PAT

3.__all__控制模块的导入行为

  from test import *时,为了防止把不需要的模块导入,在模块里边新建一个变量__all__,放上将来要使用的函数,类,全局变量的名字,如果不放,别人就无法使用__all__ =["Tset","test"]。

4. __init__.py控制包的导入行为

  ①包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py文件,那么这个文件夹就称之为包。

   ②这个__init__.py控制着包的导入行为,在这个文件中, 定义一个__all__变量,它控制着 from 包名 import *时导入的模块,如__all__ = ["sendmsg"]。

5.模块发布

  ①编辑setup.py

from distutils.core import setup
  
setup(name="dongGe", version="1.0", description="dongGe's module",author="dongGe",py_modules=['test.sendmsg', 'test.recvmsg'])

  ②构建模块

python/python3 setup.py build

  ③生成发布压缩包

python/python3  setup.py sdist

6.模块安装使用

  ①找到模块的压缩包。

  ②解圧。

  ③进入文件夹。

  ④执行命令python setup.py install。

  ⑤模块的引入。

from 模块名 import 模块名或者*

7.给程序传参数

import sys
name = sys.argv[1]

8.循环导入

  ①循环导入就是程序在导入某个模块的过程中,该模块里的函数又需要导入自身的这个模块,如此进入死循环。

  ②避免循环导入:所有在开发的过程中,开发者们写的模块不能相互调用,即应该相互隔开,然后由架构师来负责整体的模块调用使用,也就是上下设计分层,降低耦合。

9.重新导入模块

  模块被导入后,如果某一方更新了这个模块,但是import module不能重新导入模块,重新导入需用from imp import *,然后再使用reload(test)即可重新导入。

十、Python基础补充

1.常用关键字

if/else/for/break/import/class/None/not/in/from/return/elif/and/or/True
False/try/except/global/lambda/pass/raise/del/def/continue/finally/as/while

2.静态语言

  先确定功能,再执行。 

3.动态语言

  写完代码,运行的一霎那,功能才被确定。

4.输入强制转换为公式

  如在转换输入类型的时候使用func_new = eval(func_new)就可转换成公式,即所有的输入都将转换为输入,与int是一个道理。

5.is和==的区别

  ①判断两者内容用==。

  ②判断两者是否指向同一个用is。

  ③如果是数字则在-5到+125,==和is都为True,过了这个范围两者就不指向一个对象了。

推荐阅读