zoukankan      html  css  js  c++  java
  • python 基础 day8

    pickle.load:切记,如果写入文件的是类,一定要先导入相关的类

    一、上节回顾补充

    二、面向对象(下) 成员

      1、字段 2、方法 3、属性

    三、成员修饰符

    四、特殊成员

    五、面向对象边缘

    六、异常处理

    七、设计模式之单例模式

    一、上节回顾补充

      面向对象基本知识:

        1、类和对象的关系

        2、三大特性: 封装、继承、多态(多种形态、多种类型)

    多态

    def func(arg):        #python中不用指定参数arg类型
        print(arg)
    func(1)               #可以三数字
    func("alex")          #可以三字符串
    func([11,22,33,])     #可以三列表

    在C#/java中 必须制定参数类型,下面用python的方式举例:

    def func(A arg): #必须指定类型 
        print(arg)
                    
    func(123)
    func("alex") #报错(如果不是int类型就报错)
                
    class A:
        pass
    class B(A):
        pass
    class C(A):
        pass
    #arg 参数:必须是A类型或A的派生类类型
    def func(A arg): #这里必须指定父类A,但arg的类型的类型可以三A、B、C
        print(arg)

    二、面向对象中 成员

    字段:

      静态字段、普通字段

    ps:静态字段在代码加载时已经创建

    class foo:
        #字段(静态字段)属于类,用类调用
        cc = 123
    
        def __init__(self):
            #字段(普通的字段)保存在对象里,用对象调用
            self.name = 'alex'  #如果没有创建对象,那么内存里就没有普通字段

    一般情况:自己访问自己的字段

    class Province:
        country = "中国"
    
        def __init__(self,name):
            self.name = name
    
    hn = Province("河南")
    hb = Province("河北")
    print(hn.name)  # 在对象里用对象访问
    print(Province.country)  # 在类里用类访问
    # 在Python里也可以用对象访问静态字段
    print(hn.country)

    规则:
        普通字段只能用对象访问
        静态字段用类访问(万不得已不要用对象访问)

    方法: 所有方法属于类(在其他语言里只有两种方法

    1、普通方法:至少一个self,对象执行

    2、静态方法:任意参数,没有self,类执行

    3、类方法:至少有一个cls参数,由类执行

    class Province:
        country = "中国"
    
        def __init__(self,name):
            self.name = name
        #普通方法,由对象去调用执行(方法属于类)
        def show(self):
            print(self.name)
    
        #静态方法,由类调用执行(操作1、2、之后变成静态方法)
        @staticmethod #2、加上@staticmethod
        def f1(): #1、参数里去掉self,可以有其他参数
            print("....")
    
        #类方法(静态方法的一种)
        @classmethod
        def f2(cls): #至少必须有一个参数cls,自动传递参数返回类名
            #cls #类名,()创建对象
            #cls()
            print(cls) #类名<class '__main__.Province'>
    
        def f3(self):
            return self.name[1]
    
    obj = Province("河南")
    obj.show()
    Province.f1()
    Province.f2()  #<class '__main__.Province'>
    ret = obj.f3()
    print(ret)     #南 

    属性

      不伦不类的东西

      具有方法的写作形式,具有字段的访问形式

    class Page:
        def __init__(self,all_count):
            self.all_count = all_count
    
        @property   #属性就需要加上property这个方法
        def all_pager(self):
            a1,a2 = divmod(self.all_count,10)
            if a2 == 0:
                return  a1
            else:
                return a1 + 1
    
        @all_pager.setter  #函数名.setter ,设置
        def all_pager(self,value):      #函数名都和上一个相同
            print(value)
    
        @all_pager.deleter  # 删除
        def all_pager(self):
            print("del")
    
    #all_pager没有加上属性之前,用下面形式操作
    #p = Page(101)
    # r = p.all_count #字段
    # result = p.all_pager() #方法
    # print(result)
    
    #all_pager加上属性之后
    p.all_count = 102
    del p.all_count  #删除方法的字段
    ret = p.all_pager #属性 (属性和方法区别就是少了括号)
    print(ret)
    
    p.all_pager = 111 #用属性重新定义
    del p.all_pager  #用属性删除,伪删除动作,里面执行什么自己定义的
    

     另一种属性

    class Pager:
        def __init__(self,all_count):
            self.all_count = all_count
    
        def f1(self):
            return "f1"
    
        def f2(self,value):
            print(value)
    
        def f3(self):
            print("f3")
    
        foo = property(fget=f1,fset=f2,fdel=f3) #还可以按顺序直接给值
    
    p = Pager(101)
    ret = p.foo
    print(ret)
    
    obj = Pager(110)
    obj.foo = "f2"
    
    del obj.foo
    
    #结果
    f1
    f2
    f3
    

    三、成员修饰符

      私有的: 只能类自己本身的成员访问调用,其他类不能访问

      公有的: pass

    class Foo:
        def __init__(self,name,age):
            self.__name = name #加两个下划线,只能在类的内部访问,外部访问不到
            self.age = age
    
        def f1(self):
            print(self.__name)
    
    class Bar(Foo):
        def f2(self):
            print(self.age)  #这里如果写成self.__name则外面获取obj1.f2()会报错
    
    obj = Foo("alex",13)
    #print(obj.__name)  #会报错,外部不能访问
    
    obj1 = Bar("Q",12)
    obj1.f2()   #继承也不能执行__name,只能本身类内部访问
    obj1.f1()
    #print(obj._Foo__name) #(可以取到私有的,不到万不得已不要强制访问)

    四、特殊成员

    构造方法 __init__
    析构方法 __del__  :垃圾清除之前自动执行 类的__del__方法(有就执行没有不执行)

     __call__ :对象加括号,就会自动执行__call__方法

    __str__:直接打印对象,就会自动执行__str__方法

    __getitem__:获取

    __setitem__:设置

    __delitem__:删除

    class F:
        #构造方法
        def __init__(self,name,age):
            self.name =name
            self.age =age
        #析构方法
        def __del__(self):
            pass
    
        def __call__(self, *args, **kwargs):
            print("123")
    
    
        def __str__(self):
            return "%s" % self.name
    
        def __getitem__(self, item):
            # print(item.start)#obj[1:2] 中的1
            # print(item.stop)#2
            # print(item.step) #步长
            return "getitem"
    
        def __setitem__(self, key, value):
            #key.star key.stop key.step
            return "setitem"
    
        def __delitem__(self, key):
            # key.star key.stop key.step
            print("del item")
    p = F("QL",12)
    print(p.__class__) #<class '__main__.F'>
    
    obj = F("QL",15)
    #语法对应关系
    ret = obj["ad"] # 自动执行getitem方法,自动赋值给item
    ret1 = obj[1:2] #切片 会执行getitem方法
    print(ret1)
    obj[1:4] = [11,22,33,44,55,66,] #自动执行setitem方法
    del obj[1:3] #自动执行 delitem
    print(obj) #直接打印对象,就会自动执行__str__方法
    obj()   #对象加括号,就会自动执行__call__方法
    # #ret = obj["k1"] = 111 #自动执行setitem方法
    # #print(ret)
    #
    # del obj["k1"]  #自动执行delitem方法
    
    
    
    obj() #加上__call__方法才能执行(对象后加括号)
    
    #F()() #也可以写成这样
    
    print(obj) #不加str会输出内存地址<__main__.F object at 0x0000000000726630>,加上__str__会友好显示,str里返回什么就输出什么
    
    #__dict__ #获取对象中封装的数据 【重要】
    ret = obj.__dict__
    print(ret) #{'age': 12, 'name': 'QL'}
    
    #print(F.__dict__)#获取类中的成员
    

     __iter__

    class F1():
        def __iter__(self): #iter是生成器(里面有yield就是生成器)
            #yield 1
            #yield 2
            return iter([11, 22, 33, ])
    
    obj = F1()
    for item in obj:#默认不可以迭代,加上iter方法才可以迭代
        print(item)#默认执行iter方法,迭代iter返回值
    

    五、面向对象边缘

      - insinstance 查看某个对象是不是某个类创建的

      - issubclass 查看某个类是不是某个类的子类

    class A:
        pass
    
    class B(A):
        pass
    
    obj = A()
    ret = isinstance(obj,B)
    
    class Bar:
        pass
    
    class Foo(Bar):
        pass
    
    obj = Foo()
    #obj,Bar(obj类型和obj类型的父类)的实例
    ret2 = isinstance(obj,Bar) #查看obj是不是Bar创建的
    print(ret2) #True
    ret1 = issubclass(Bar,Foo)# 查看Bar 是不是Foo的子类
    print(ret1) #False
    

     主动执行父类方法:

    class C1:
    
        def f1(self):
            print("c1.f1")
    
    class C2(C1):
    
        def f1(self):
            # # 主动执行父类的f1方法
            super(C2,self).f1()
            print("c2.f1")
    
            #C1.f1(self) #不建议使用,用上面的super方法
    
    obj1 = C2()
    obj1.f1()
    

     有序字典

    class MyDict(dict):
    
        def __init__(self):
            self.li = []
            super(MyDict, self).__init__()
    
        def __setitem__(self, key, value):
            self.li.append(key)
            super(MyDict, self).__setitem__(key,value)
    
        def __str__(self):
            temp_list = []
            for key in self.li:
                value = self.get(key)
                temp_list.append("'%s':%s"% (key,value))
            temp_str = "{" + ",".join(temp_list) + "}"
            return  temp_str
    obj = MyDict()
    obj["k1"] = 123
    obj["k2"] = 456
    print(obj) #继承父类的setter
    #结果
    {'k1': 123, 'k2': 456}
    

     六、异常处理

    while True:
        num1 = input('num1:')
        num2 = input('num2:')
        try:
            li = [11, 22]
            print('li[100]') #indexerro
            num1 = int(num1)
            num2 = int(num2)
            result = num1 + num2
    
    
        except ValueError as ex:  #只捕获ValueError错误 从上往下捕获
            print('ex')
        except IndexError as ex:
            print('ex')
        except Exception as ex:  # ex 是Exception的一个对象,Exception捕获所有错误
            print('ex')  # str
    

     完整代码块

    try:
        pass
    except ValueError as ex:
        print(ex)
    except Exception as ex:
        print(ex)
    else:  #上面不报错执行else
        pass
    finally: #不管报不报错都执行finally
        pass
    

     主动触发异常

    try:
        raise Exception('主动错误一下') #self.message = '主动错误一下’
        print(1234)
    except ValueError as ex:
        print(ex)
    except Exception as ex:#__str__,return self.message
        print(ex)
    else:  #上面不报错执行else
        pass
    finally: #不管报不报错都执行finally
        pass
    

     断言

    assert 1==1 #如果条件成立不报错
    
    assert 1==2 #如果条件不成立报错
    
    p = obj()
    p.start() #在执行start之前先执行一个 p.status == False,就可以在start中写入(assert p.staus == False)
    

    七、设计模式之单例模式(23种,推荐书《goF设计模式》)

      单例模式: 用来创建单个实例

    class Foo:
    
        instance = None
    
        def __init__(self,name):
            self.name = name
        @classmethod
        def get_instance(cls):
            #cls 类名
            if cls.instance:
                return  cls.instance
            else:
                obj = cls("alex") #一般是固定值,也可以传参
                cls.instance = obj #对象赋值给instance
                return obj
    obj1 = Foo.get_instance()
    print(obj1)
    obj2 = Foo.get_instance()
    print(obj2)
    

     

    谁来访问都创建一个,比较浪费,不如只创建一个,都来访问这一个。

     

  • 相关阅读:
    深入浅出 Java 8 Lambda 表达式
    OneAPM x 腾讯 | OneAPM 技术公开课·深圳 报名:前端性能大作战!
    第30节:Java基础-内部类
    第二十九节:Java基础知识-类,多态,Object,数组和字符串
    第二十九节:Java基础知识-类,多态,Object,数组和字符串
    第二十九节:Java基础知识-类,多态,Object,数组和字符串
    第二十八节:Java基础-进阶继承,抽象类,接口
    第二十八节:Java基础-进阶继承,抽象类,接口
    第二十八节:Java基础-进阶继承,抽象类,接口
    ES6教程-字符串,函数的参数,了解函数的arguments对象,js面向对象,设计模式-单例模式,解构赋值
  • 原文地址:https://www.cnblogs.com/QL8533/p/5620638.html
Copyright © 2011-2022 走看看