Python 基础总结篇

1`变量 & 关键字
    变量: 可以和Java命名规范类比使用   24个英文字母,数字,下划线,数字不能作为变量的开头.
    关键字: class def del if else elif break continue return try finally True False     
        Python 命名查看
            import keyword  
            keyword.kwlist --> 以列表形式返回的关键字

2` 输入与输出
    输入: input()
        python2: 3+4 ---> 7 
        Python3: 3+4 ---> "3+4"

        如果录入的非整形数字 Python2 需要使用 raw_input()函数,而Python3可以很好的兼容整形和字符型,已经舍弃了raw_input()函数,只保留了input()
    输出换行: print()
        print()是一个多参函数,其中"end = /n" 默认定义在print()中.
        而Python2中是没有该参数的,怎么办呢?import from __ future __import print_function   这样呢使用print()和3使用的方法就一致了.


3`判断语句
    if  是否满足条件 :
        pass
    elif 是否满足条件:
        pass
    elif 是否满足条件:
        pass
    else:
        pass 

    if 什么时候为 True : 
        a.True
        b.非0数字
        c.字符串不为None
        d.数组不为空
        e.集合不为空
        f.元组不为空
        g.字典不为空
4`循环 for while 
    for i in range(10)   [0,~,9]
        print(i)      ---> 0,1,2,3,4,5,6,7,8,9

    while(True):
        不断的循环做某件事

        break   #跳出循环体
        continue #结束本次循环,继续下次循环

5`字符串""str ,列表[]list ,元组()tuple ,集合{}set ,字典 {key,value} dict
    字符串 str : "a" or 'a'
            a = "abcd"
            a.find("a") --> 0  若找不到元素,程序崩溃
            a.find("e") --->程序崩溃

            a.index("a") -->0
            a.index("l") --> -1  找到元素返回对应元素的角标值,找不到返回-1

            a[:3]  --> abc  从角标0取值角标2  含头不含尾
            a[::2] --> ac  以2为步长
            a[::-1] --> dcba 反转

    列表[]   b = ["11","22","33","44"]  增删改查 ,可以存储不同数据类型
             len(b)  获取list b 的长度
             b.append("55")  添加数据
             b.remove("11")  删除数据
             b.pop() 删除最后一个元素
             b[2] = "bb"  修改角标为2的元素值
             for i in b :
                print(i)   遍历列表B

    元组() tuple c = ("22","33")  只能查看,不能修改数据

    集合 {} set d = {"11","2","33"}  增删改查 ,可以存储不同数据类型 

    字典 dict e = {key:value}    
            什么数据类型可以当做key? 不可变数据-->数字,字符串,元组
                                  可变数据类型 --> 列表,集合,字典

            遍历字典的四种方式:
                1` 根据keys返回所有key的元组,根据key查找对应的value
                a = {"name":"xiaoming","age":10 }
                for temp in a.keys():
                    print(temp)

                2` 根据values返回所有的value元组,遍历元组
                for temp in a.values():
                    print(temp)

                3` 根据items()返回所有的key values
                for temp in a.items():
                    print(temp)

                4` 遍历items,返回所有的项,
                for key,value in a.items():
                    print("key=%s,value=%s"%(key,value))


6`函数  被 def 关键字修饰的
    1`形参
        def text (a):--> a就代表形参,在调用text方法时,需要且必须传递a这样的实参

    2`缺省参数 顾明思议可以省略的实参,也可以传递实参
        a > def text (a,b = 10):

            调用 text("haha") b默认=10,or text("haha",20) b = 20   

        b > def text(a,b = 10,c = 20)
            调用:
                text("a") 默认 b = 10,c = 20
                text("a",5)  b = 5, 但是c依旧还是20
                text("a",5,10) b = 5, c = 10 

                text("a",c = 4)  b 默认 10,只改变 c = 4

    3`不定长参数  可能需要一个函数能处理比当初声明时更多的参数
        a > def text (a,b,*args)

            调用:
                text("a",10,23,34,45,55)   实参 必须要传递给形参a,b 这两个参数. 除此之外,实参如果附带有多余的参数,那么剩下的 都将传递给不定长参数, 不定长参数会返回一个 元组类型的数据结构

        b > def text (a,b,*args,**kwargs)
            
            调用:
                text("a",1,22,33,44,55,age=10)
                print(a) ---> "a"
                print(b) --> 1
                print(args) --> (22,33,44,55)
                print(kwargs) ---> {"age":10}

        c > 总结:
            在形参中 如果出现了*args -- 那么打印args的话会返回一个元组类型的数据
                    如果出现了**kwargs -- 那么打印kwargs的话会返回一个字典类型的数据 
                        怎么保证kwargs中有数据存在呢?
                            实参需要特别的传递   key = value 的格式
                            比如:
                                text(1,2,key = "haha")    --> 此时 a = 1   b = 2  而 args = ()  kwargs = {"key" : "haha"}
                            若
                                text(1,2,33,key = "haha")    -->此时 a = 1 b = 2  而 args = (33,)   kwargs = {"key" : "haha"}
                            若
                                text(1,2,33,44,key = "haha")     -->此时 a = 1 b = 2  而 args = (33,44)  kwargs = {"key" : "haha"}

                            所以当 args 中只包含一个元素的时候,元素后面会跟加逗号,注意元组只能做第一赋值操作,不能改变(添加,删除),只能查看

    4`在python中没有重载的概念,即在一个.py文件中,不能存在函数,方法名相同的情况.                       

    5`函数 返回值
        return 用于结束一个方法体,并返回数据,一个函数体中可以使用多个 return,但是执行完return之后,就不会执行return下面的代码块.

    6`局部变量,成员变量
        局部变量 --> 定义在函数中的变量,成为局部变量,当方法执行完毕,且在内存中没有指针指向该函数,由垃圾回收器回收.在其他函数中是不可以调用的.
        成员变量 --> 定义在类中,方法外,可以在任何地方进行调用, 赋值运算,但在操作成员变量方法执行完毕之后,成员变量不会改变.如果想在方法中修改成员变量,那么需要 global 关键字进行修饰.   

        总结:
            在函数中不使用global关键字声明全局变量时,不能修改全局变量,其本质是:不能修改全局变量的指向,进而改变不了全局变量.
            对于不可变数据类型来说,因其指向的数据不能修改,所以不使用global关键字无法改变成员变量 <数字,字符串,元组>
            对于不可变数据类型来说,因其指向的数据可以修改,所以即使不使用global关键字,也可以修改成员变量 <数列,集合,字典>


7`文件 
    1`文件的打开 & 关闭
        打开:f <File 返回值> = open("文件名","访问模式 w | r")  默认 r 只能读
        关闭:close()   文件流必须要关闭!!! 

    2`文件访问模式
        w 以写的方式打开文件,如果该文件存在,直接覆盖,如果不存在该文件,创建一个新文件. 
        r 以只读的方式打开文件,默认指针放在文件的开头.
        a 打开一个文件用于追加,如果一个文件存在,那么指针放在文件的末尾,也就是说,新的内容会被写入到文件的末尾处,如果文件不存在,那么创建一个文件.

    3`文件的读写
        读  
            read(num) 按字节的形式读.只读num个字节,参数可不传,如果指定了字节的个数,那么只读num个字节,如果没有指定,那么将整个文件都读出来.
            readLine() 按文件行读.只读一行.
            readLines() 按文件行读,一次性将文件都读出来. 返回一个数列 list.
                如果文件读不出来的话,那么会返回一个空的数据,那么我们可以根据读的东西是否为空来判断文件是否读完.多次调用,文件指针会根据读的次数,不断的下移.

        写 
            write("File content ")

    4`获取当前写的位置,定位到某个位置
        查找当前位置 position  = f.tell()

        定位某个位置 f.seek(offset,from)
            参数说明:
                offset: 偏移量
                from :方向
                    0 文件开头
                    1 当前位置
                    3 文件末尾

            例:
                def textW():
                    f = open("text.txt","w")
                    f.write("hello,python")
                    position = f.tell() #获取当前的位置
                    print(position)

                    f.close()


                def textR():   
                    f = open("text.txt","r") 
                    f.seek(5,0)  #定位读的位置,文件的开头,偏移五个字节开始读
                    content = f.read()
                    print(content)    
                    f.close()


                textW()    ----> 12
                textR()    ---> ,python 

    5`强大的 os 模块
         导入 os 模块   import os
        1` 文件重命名:os.rename("需要修改的文件名","需改后的文件名")
        2` 删除文件:os.remove("文件名")
        3`创建文件夹:os.mkdir("文件夹名")
        4`删除文件夹:os.rmdir("文件夹名")
        5`获取当前文件路径:os.getcwd()
        6`修改当前文件路径:os.chcwd("../")
        7`获取目录列表:os.listdir("文件目录")

8`面向对象  类 & 对象
    类: class 关键字修饰 抽象的,一类事物的属性和行为.
    对象: 具体的,真实存在的.

    1`面向对象三大特征:
        封装,继承,多态.

        1`封装: 私有的,外界访问不到的 注意: 被 __xxx__ "__" 修饰的不是封装,仅仅是封装一种表现形式.
        2`继承: 子类继承父类 顶层默认 object
            class Demo (object):
                pass
                1`子类不能继承且不能使用 父类私有的属性及私有方法.
                2`私有属性,不能通过对象直接访问,但可以通过方法访问.
                3`在Python中子类支持多继承,如果多个父类有相同的方法名,但方法体不一致,在不指定调用那个父类方法前,默认调用继承的第一个父类方法体.
                4`重写父类方法.如果子类中声明了和父类中一模一样的方法名以及方法形参,此时,子类不在调用父类实现的方法体,称为重写.
                                    class Animal(object):
                                        def eat(self,a):
                                            print("Animal eat ")

                                    class Cat(Animal):
                                        def eat(self,a):    #子类重写父类的方法
                                            print("Cat----eat---")

                                    c = Cat()
                                    c.eat()  ---> Cat----eat---
                        如果子类声明的方法名和父类方法名一致,但方法形参不一致,此时不是重写,子类默认调用自己声明的方法,不在调用父类方法

                                    class Animal(object):
                                        def eat(self,a):
                                            print("Animal eat ")

                                    class Cat(Animal):
                                        def eat(self):
                                            print("Cat----eat---")

                                    c = Cat()
                                    c.eat()  ---> Cat----eat---   #但是此刻子类并没有重写父类的eat()方法,子类只能调用自己的方法


                    调用父类方法
                        1`通过super 只仅限于单继承.
                            super().XXX()

                        2`通过父类名 单继承或者多继承都可以.
                            Animal.XXX(),  指定父类,调用其方法.

                5`类属性,实例属性
                    
                                


        3`多态:父类引用指向子类对象
                 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)



    2`魔法方法,在Python中方法名如果是"__XXX__",那么就具备特殊的功能,所以称为魔法方法
            1`__new__(cls):创建对象,返回一个id,对象内存地址值,该方法不必手动调用,Python解析器自动调用.
                        注意:
                        1`至少需要一个参数 cls ,代表要实例化的类,此参数在实例化时由Python解释器自动提供
                        2`__new__ 方法必须要有返回值,返回实例化出来的实例,这点一点要注意!!! 可以 return object.__new__ 的实例,也可以 return 父类 __new__ 的实例,
                          否则对象创建失败
                        

            2`__init__(self):初始化函数,可以用来完成一些默认的设定.
                        注意:1`__init__(self)在创建一个对象时默认被调用,不必手动调用.
                            2`__init__(self),默认有一个形参,如果在创建对象的时候,传递了两个实参,那么__init__方法有三个形参,
                                即:__init__(self,x,y).
                            3`__init__(self),参数self调用者不必传递,Python解释器会自动把当前的对象引用传递进去

              __new__ 与 __init__ 方法的区别:
                    1` 调用时机不同.__new__ 创建方法时调用,返回一个实例. 而 __init__ 初始化对象的时候调用,它需要一个 self 参数,而这个参数就是 __new__ 方法返回的实例
                    2` __new__ 必须要有返回值,而 __init__ 不需要返回值,__init__ 可以在 __new__ 的基础上完成一些其他的初始化动作.
                    3` 我们可以把这两个方法理解成制造商品的流程,__new__ 相当于置办购买材料环节,而 __init__ 相当于在原始材料上进行加工,初始化材料环节.


            3`__str__(self):用于打印对象,相当于Java中的toString.如果子类不重写该方法,打印的是该对象在内存的地址值.
                        注意:当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
                        例:
                            class Cat(Animal):
                                def __init__(self,new_name,new_age):
                                        self.name = new_name
                                        self.age = new_age

                                def __str__(self):
                                    msg = "一只%s猫,今年%s岁了"%(self.name,self.age)
                                    return msg

                            c = Cat("汤姆",10)
                            print(c)   -- > #一只汤姆猫,今年10岁了



                        子类不重写 __str__(self):

                            class Cat(Animal):
                                def __init__(self,new_name,new_age):
                                        self.name = new_name
                                        self.age = new_age

                                # def __str__(self):
                                #   msg = "一只%s猫,今年%s岁了"%(self.name,self.age)
                                #   return msg


                                def __del__(slef):
                                    print("--------del-----")   


                            c = Cat("汤姆",10)
                            print(c)   --- >  #<__main__.Cat object at 0x105dcc910>


            4`__del__(self):删除对象时,Python也会自动调用一个方法,即__del__(self)
                        注意:1`当有一个变量保存了对象的引用时,此对象的计数就会加1
                            2`当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除
                            例:
                                class Cat(Animal):
                                    def __del__(slef):
                                        print("--------del-----")   


                                c = Cat()   #当一个变量保存了对象的引用,此对象的计数就会加1
                                c1 = c          
                                c2 = c

                                print("------ 马上干掉了- c")
                                del(c)

                                print("------马上干掉了- c1")
                                del(c1)

                                print("------马上干掉了- c2")
                                del(c2)

    3`类属性,实例属性
        类属性:
            类属性就是类对象所拥有的属性,它属于类对象和实例对象的共享属性,在内存中只存在一个副本,和Java中的静态类似.对于类属性,可以通过类对象或者实例对象访问.
                class People(object):  
                    name = "xiaoming"  #公有类属性
                    __age  = 10     #私有类属性

                #调用:
                p = People()
                print(p.name)   # 通过对象实例调用类属性
                print(People.name)  #通过类对象调用类属性

                print(People.__age) #执行程序崩溃,在类外,不能调用类的私有属性


            通过实例对象修改类属性
                p.name = "xm"  #修改类属性
        


        实例属性:
            顾明思议,就是实例对象定义的属性 上面接触的都是实例属性.只能通过实例对象进行访问
            class People(object):  
                name = "xiaoming"  #公有属性
                __age  = 10     #私有属性


                def __init__(self):
                    self.address = "shandong"   #实例属性
                    


            p = People()
            print(p.name)   # xiaoming
            print(p.address) #shandong  ---> 实例属性只能通过实例对象访问


        私有属性:
            私有属性,其目的是为了保证数据安全,外界不能直接访问,在类中可以对外暴露出一个公共的方法,供外界访问.私有属性可以是私有类属性,也可以是私有实例属性.
            class People(object):  
                name = "xiaoming"  #公有类属性
                __age  = 10     #私有类属性


                def __init__(self):
                    self.address = ""
                    self.__phone = "" #私有实例属性
                    


                def setAge(self,new_age):   #对外暴露修改私有类属性方法
                    self.__age = new_age

                def getAge(self):       #获取私有类属性
                    return self.__age


                def setPhone (self,new_phone):  # 对外暴露修改私有属性方法
                    self.__phone = new_phone

                def getPhone (self):    #获取实例私有属性
                    return self.__phone     


            p = People()
            p.name = "xm"  #修改类属性
            print(p.name)   #--->xm

            p.setAge(20)    
            age = p.getAge()
            print(age)      # ---> 20

            p.setPhone("12344")
            phone = p.getPhone()
            print(phone)        # ---> 12344

        总结:
            1`类属性,包括,公有类属性和私有类属性,可以直接通过类名.类属性调用,也可以通过实例对象调用,但是在类外,不能直接访问类私有属性,需要对外提供公共的方法.
            2`类属性,在内存中只存在一个副本,而实例属性,是根据实例对象而变化的.
            3`类属性,和Java中静态属性有点相像.

        注意点:
            类属性访问方式虽然有两种,但是在类外,必须通过类对象去修改类属性!!!如果通过实例对象修改类属性,那么实例对象会产生一个和类属性同名的实例属性,而此时实例对象并没有修改类属性,而是修改的实例对象的
            实例属性,不会影响到类属性,并且之后,实例对象去引用该名称的属性,实例属性会屏蔽掉类属性,即引用的是实例属性,就近原则.除非,删除了实例属性.

            比如:
                class People(object):  
                    name = "xiaoming"  #公有类属性
                    __age  = 10     #私有类属性


                p = People()
                p.name = "xm"  #通过实例对象,修改类属性.实例对象产生了和类属性同名的对象属性,没有修改类属性.并且对象属性屏幕了类属性,此时通过对象获取属性,是对象的属性,并不是类属性
                print(p.name)       # xm    获取的是对象刚刚创建的实例属性,并不是类属性
                print(People.name)  # xiaoming

                del p.name   #删除实例对象属性
                print(p.name)

            打印信息:
                xm
                xiaoming
                xiaoming



    4`静态方法 & 类方法 实例方法:
        静态方法:
            被 @staticmethod 标识符,所修饰的方法,成为静态方法.静态方法不需要多定义参数.

            class People(object):  
                name = "xiaoming"  #公有类属性
                __age  = 10     #私有类属性

                @staticmethod  #声明静态方法
                def getName():
                    return People.name  

            print(People.getName())

        类方法:
            类方法是类对象所拥有的方法,需要用修饰器 @classmethod 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般习惯 cls 声明形参.能够通过实例对象和类对象进行访问.
            class People(object):  
                name = "xiaoming"  #公有类属性
                __age  = 10     #私有类属性


                def __init__(self):
                    self.address = ""
                    self.__phone = "" #私有实例属性
                    

                @classmethod
                def setAge(cls,new_age):    #对外暴露修改私有类属性方法
                    cls.__age = new_age

                @classmethod    #声明类方法
                def getAge(cls):        #获取私有类属性
                    return cls.__age


                def setPhone (self,new_phone):  # 对外暴露修改私有属性方法
                    self.__phone = new_phone

                def getPhone (self):    #获取实例私有属性
                    return self.__phone     

            调用:  
                p = People()
                p.setAge(20)    #通过实例对象调用
                age = p.getAge()
                print(age)

                print(People.getAge())      #通过类对象直接访问, 打印出的都是20


        实例方法: 
            即在类中,没有@classmethod 也没有 @staticmethod 修饰的方法,称为实例方法.只能通过实例对象进行访问.
            在声明实例方法的时候,需要参数 self

        总结:
            1`从静态方法,类方法,以及实例方法的定义形式上来看,静态方法需要 @staticmethod 修饰符修饰,不需要参数,类方法需要 @classmethod 修饰符修饰,需要 cls 参数,而 实例方法不需要修饰符进行修饰
                需要 self 参数.
            2`通过cls引用的必定是类属性或者类方法,不会是实例属性,因为先加载类.
              通过self引用的有可能是类属性,也有可能是实例属性,这个需要具体分析.
              静态方法不需要定义额外的参数,所以在静态方法中,引用类属性,必须通过类对象来引用.


    5`单例模式
        所谓单例,即只存在一个实体对象.    
            class Instace(object):
                __instace_Tag = None  #私有类属性

                def __new__(cls):   
                    if cls.__instace_Tag == None:
                        cls.__instace_Tag = object.__new__(cls)     #保证创建一次对象
                        return cls.__instace_Tag;
                    else:
                        return cls.__instace_Tag    


9`异常
    try : 
        # 可能存在有问题的代码
    except :
        # 发生error处理操作

    例:
        try :
            print(hello)
        except:
            print("----Error----")


    1` except 后面不跟随 异常类型 ,默认捕获所有异常类型.

            try :
                print(b)
            except Exception as errorMsg:  # Exception as errorMsg  获取异常信息,Exception是所有异常父类
                print(errorMsg)

    2` 如果 except 跟随 异常类型,那么必须保证程序崩溃的异常类型和你声明要捕获的异常类型相匹配,否则,异常捕捉失败
        
        比如:
            try :
                print(b) # b 没有定义
            except IOError as errorMsg: # 声明了IOError 异常,但是程序依旧崩溃了
                print(errorMsg)

        崩溃日志:
            Traceback (most recent call last):
              File "text_type.py", line 106, in <module>
                print(b)
            NameError: name 'b' is not defined

            日志log,报的是NameError,变量b没有声明.而程序中捕获的是 IOError,异常类型,匹配失败,程序崩溃.


    3` except 捕捉多异常类型
            1`  
                try :
                    print(b)
                except (IOError,NameError):
                    print("errorMsg")

            2` 
                try :
                    print(b)
                except IOError as ioErrorMsg:
                    print(ioErrorMsg)

                except NameError as nameErrorMsg:
                    print(nameErrorMsg) 


    4` else:
            对于else 并不陌生,一般和if一起使用.在异常中,同样可以使用. 但是必须和 except 代码块结合使用
            else 作用域:
                1` if else 
                2` try ... except ... else ...

            else 没有捕获到异常的时候,执行该语句体.

            比如:
                程序正常运行:
                    try :
                        b = 10
                        print(b)
                    except Exception as errorMsg:
                        print(errorMsg) 
                    else:
                        print("没有捕获到异常,程序正常运行")

                    log日志:
                        10
                        没有捕获到异常,程序正常运行  , 执行 else 语句体

                程序发生异常:
                    try :
                        # b = 10
                        print(b)
                    except Exception as errorMsg:
                        print(errorMsg) 
                    else:
                        print("没有捕获到异常,程序正常运行")

                    log日志:
                        name 'b' is not defined  并没有执行 else 语句体

    5` finally  : 无论有没有发生异常,一定会走 finally 代码块. 作用域: 只能在 try ... except ... finally 或者 try ... finally 语句体中使用.
        使用场景:比如关闭文件流
            例如:
                try ... except ... finally: 

                    try :
                        b = 10
                        print(b)
                    except Exception as errorMsg:
                        print(errorMsg) 
                    else:
                        print("没有捕获到异常,程序正常运行") 
                    finally :
                        print("--------finally--")  

                代码执行效果:
                    10
                    没有捕获到异常,程序正常运行
                    --------finally--

                或者: try ... finally
                    try :
                        print(b)    
                    finally :
                        print("--------finally--")


                    代码执行效果:
                        --------finally--
                        192:飞机大战 zhaoyanhui$ python text_type.py 
                        --------finally--
                        Traceback (most recent call last):
                          File "text_type.py", line 106, in <module>
                            print(b)
                        NameError: name 'b' is not defined      
大概总结了这么多,不过,针对重写这方面还是有点疑惑,重写,只与子父类方法名有关,而与方法参数无关,还是必须保证两者方法名及方法形参一致?如果您有答案,请告诉我,感激不尽!!!作为一名小白,上面总结难免有错误,也请您告诉我,感激不尽!!
    原文作者:coke_可乐
    原文地址: https://www.jianshu.com/p/edbaf0b7cbda
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞