• Python 3学习 ——面向对象


    Python 学习——面向对象

     写此博客 是为了激励自己,并且将自己的心得以及遇到的问题与人分享

    一、面向对象基础

                    面向对象就是一个类和对象的应用。

      1.定义方法:

    ----------------------------------------------------------------

        class 类名:

          def 方法名(self , arg):

          print(arg)

        中间人 = 类名()

        中间人.方法名(arg)

    ----------------------------------------------------------------

    self 代指,调用方法的 对象 (中间人)

      2.构造方法:类名加()自动执行构造方法

     1 class Person:
     2     def __init__(self,name,age):
     3         self.n = name
     4         self.a = age
     5     def show(self):
     6         print("%s  %s " %(self.n,self.a))
     7 
     8 liufeiduo = Person('刘飞铎',19)
     9 liufeiduo.show()
    10 
    11 chengjunfei = Person('程俊飞',18)
    12 chengjunfei.show()

       3.继承

     1 class Father:   # 父类,基类
     2     def 篮球(self):
     3         pass
     4     def 足球(self):
     5         pass
     6     def 抽烟(self):
     7         pass
     8 
     9 class Son(Father):  # 子类,派生类
    10     def 排球(self):
    11         pass
    12 
    13 
    14 s = Son()
    15 s.篮球()

      子类重写父类方法

     1 class F:
     2     def f1(self):
     3         print('F,f1')
     4     def f2(self):
     5         print('F,f2')
     6 
     7 class S(F):
     8     def s1(self):
     9         print('S,s1')
    10     def f2(self):
    11         print('S,s2')
    12 
    13 obj = S()
    14 obj.s1()    #S,s1  s1中的self 是形参,此时代指 obj
    15 obj.f2()    #S,s2     

      self 永远指调用方法的调用者

      两种调用父类的方法:

              方法一: super
    class
    F: def f1(self): print('F,f1') def f2(self): print('F,f2') class S(F): def s1(self): print('S,s1') def f2(self): super(S,self).f2() #执行父类中的f2方法 #super代指了它的父类 print('S,s2') obj = S() obj.f2() ''' F,f2 S,s2 '''
              方法二:通过父类名调用方法
    class
    F: def f1(self): print('F,f1') def f2(self): print('F,f2') class S(F): def s1(self): print('S,s1') def f2(self): #super(S,self).f2() #执行父类中的f2方法 #super代指了它的父类 print('S,s2') F.f2(self) obj = S() obj.f2() ''' S,s2 F,f2 '''

      多继承:Python 与 C++ 独有支持多继承,一个子类可以继承多个父类。

     1 class F1:
     2     def a(self):
     3         print('F1.a')
     4 
     5 class F2:
     6     def a(self):
     7         print('F2.a')
     8 
     9 class Son(F1,F2):   # 按照从左到右的顺序,"一条路找到黑的顺序"来进行找。 如果有同一个根时,根最后执行。
    10     pass
    11 
    12 obj = Son()
    13 obj.a()     #F1.a

       4.多态

    1 def func(arg):
    2     print(arg)
    3                  #   Python 中的原生多态,不被类型所限定。
    4 func(1)
    5 
    6 func('llalala')

    二、面向对象中级

      1.类成员

        字段

          普通字段,保存在对象中,执行只能通过对象访问。

          静态字段,保存在类中,在内存中只保存一份,执行时可以通过对象访问也可以通过类进行访问。

    1 class Provience:
    2     country = '中国'
    3 
    4     def __init__(self,name):
    5         self.name = name
    6 henan = Provience('河南')
    7 print(Provience.country)    #中国
    8 print(henan.name)    #河南

        方法

          普通方法,保存在类中,由对象来进行调用。self --> 对象

          静态方法,保存在类中,由类直接调用。

          类方法,保存在类中,由类直接调用。cls --> 当前类

     1 class Foo:
     2 
     3     def bar(self):  #普通方法
     4         print('bar')
     5 
     6     @staticmethod
     7     def sta(a1,a2):  #静态方法   self 就不是必须存在的了
     8         print(a1,a2)
     9 
    10     @classmethod
    11     def classmd(cls):  #类方法  cls 是类名 不依赖对象 可以通过类直接执行
    12         print(cls)
    13         print('classmd')
    14 
    15 object = Foo()
    16 object.bar()    #bar
    17 
    18 Foo.sta(2,4)   #2 4 调用者直接类调用就可以了
    19 
    20 Foo.classmd()    # <class '__main__.Foo'>  classmd

      应用场景:

          如果对象中需要保存一些值,执行某功能时,需要使用对象中的值 --->  普通方法。

          不需要任何对象中的值 ---> 静态方法。

      类的成员——属性:按照方法的方式写,按照字段调用的方式调用。

     1 class Foo:
     2     def __init__(self):
     3         self.name = 'a'
     4 
     5     def bar(self):
     6         print('bar')
     7 
     8     @property  #通过property装饰器
     9     def per(self):  # 属性:  伪造成方法,但访问的时候使用的是字段的方式
    10         print('per')
    11 
    12 obj = Foo()
    13 obj.per

      利用 属性 完成分页的功能:

    class Pergination:
    
        def __init__(self,current_page):
            self.page = int(current_page)
    
        @property
        def start(self):
            val = (self.page - 1) * 10
            return val
        @property
        def end(self):
            val = self.page * 10
            return val
    li = []
    
    for i in range(1000):
        li.append(i)
    
    while True:
        p = input('请输入要查看的页码: ')#     每页显示十条
        obj = Pergination(p)
    
        print(li[obj.start:obj.end])

    三、面向对象高级

      1. 成员修饰符

        公有成员

        私有成员   __字段名

          - 无法直接访问,只能间接访问

          - 继承过来的私有字段是无法进行访问,内部访问指的是自身内部,继承过来的不可以。

     私有字段
    1
    class Foo: 2 3 def __init__(self,name,age): 4 self.name = name 5 # self.age = age 6 self.__age = age # 私有,外部无法直接进行访问 7 8 def show(self): #间接访问私有字段方法 9 return self.__age 10 11 obj = Foo('chengjunfei',20) 12 print(obj.name) 13 print(obj.show()) #间接访问私有字段

      2. 特殊成员

        __init__ 类()  自动执行

        __call__   对象() 类()()自动执行

     1 class Foo:
     2 
     3     def __init__(self):
     4         print('init')
     5 
     6     def __call__(self,*args,**kwargs):
     7         print('call')
     8 
     9 
    10 
    11 Foo()() #init  call
    12 
    13 object = Foo()
    14 object()    #对象后面加括号会执行 __call__ 中的方法,Python的一个内置语法。

        __int__    int(对象)

        __str__    str(对象)

        __add__  

     1 class Foo:
     2     def __init__(self):
     3         pass
     4 
     5     def __add__(self, other):
     6         return 123
     7 
     8 obj1 = Foo()
     9 obj2 = Foo()
    10 
    11 r = obj1 + obj2
    12 # 两个对象相加时,自动执行第一个对象的__add__方法,并且将第二个对象当作参数传递进去。
    13 
    14 print(r,type(r))    #123 <class 'int'>

        __del__    析构方法,当对象被销毁时,自动执行。

        __dict__    将对象中封装的所有内容通过字典的形式返回。

     1 class Foo:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6 
     7 object = Foo('刘飞铎',21)
     8 
     9 d = object.__dict__
    10 print(d)    #{'name': '刘飞铎', 'age': 21}
    11 
    12 c = Foo.__dict__
    13 print(c)    #{'__module__': '__main__', '__init__': <function Foo.__init__ at 0x0000016D6A1499D8>,
    14             #  '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>,
    15             #  '__doc__': None}

        __getitem__  # 切片(slice类型)或者索引    有返回值

        __setitem__  没有返回值

        __delitem__  没有返回值

     1 class Foo:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6 
     7     def __getitem__(self, item):
     8         return item + 10
     9 
    10     def __setitem__(self, key, value):
    11         print(key)
    12         print(value)
    13 
    14     def __delitem__(self, key):
    15         print(key)
    16 
    17 
    18 li = Foo('Liufeiduo',22)
    19 r = li[8]   #自动执行li对象中的__getitem__方法,8当作参数传递给了item
    20 
    21 print(r)    #18
    22 
    23 li[100] = 'asdf'    # def __setitem__(self, key, value):
    24 del li[985]     # def __delitem__(self, key):

        __iter__ :如果类中有 __iter__ 方法,对象 ---> 可迭代对象。

             对象.__iter__ ()的返回值,就是迭代器。

             for 循环 遇到 迭代器,就执行 next( ) 方法就行了。

             for 循环 遇到 可迭代对象,要先通过 可迭代对象.__iter__ ( )方法获取迭代器然后继续执行next( )方法。

     1 class Foo:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6     def __iter__(self):
     7         return iter([11,22,33,44])
     8 
     9 li = Foo('liufeiduo',22)
    10 #1.获取li对象的类 Foo 中的__iter__ 方法,并获取其返回值。
    11 #2.去循环上一步中返回的对象。
    12 for i in li:
    13     print(i)    # 11/r 22/r 33/r 44/r

      3. metaclass  类的祖宗

        a. 在Python中,一切事物都是对象。

        b. 

          class  Foo():

            pass

          obj = Foo()

          # obj 是对象,Foo 是类。

          # Foo 类也是一个对象,type 的对象。

        c. 类都是 type 类的对象   type(...)

         "对象"都是类的对象    类()

     1 class MyType(type):
     2     def __init__(self,*args,**kwargs):
     3         print('123')
     4         pass
     5 
     6 
     7 class Foo(object,metaclass=MyType):
     8     def func(self):
     9         print('hello')
    10 
    11 # 执行结果:  123

      类后面加括号,创建对象并不是直接执行了该类的 __init__ 方法,先执行 type 的 __call__ 方法,再执行该类的 __new__ 方法,再然后执行了 __init__ 方法。

    转自wupeiqi的博客

      

      4. 异常处理

     1 #-----------------最基本的---------------------
     2 while True:
     3     try:
     4         inp = input('请输入序号:')
     5         # 代码块,逻辑
     6         i = int(inp)
     7     except Exception as e:
     8         # e 是Exception的对象,对象中封装了错误信息。
     9         # 上述代码块出错,自动执行当前块内容。
    10         print(e)
    11         i = 1
    12 
    13     print(i)
    14 
    15 #--------------写异常的基本流程--------------------------------
    16     try:
    17         int ('w3rs')
    18     except IndexError as e:
    19         print('IndexError',e)
    20     except ValueError as e:
    21         print('ValueError',e)
    22     except Exception as e:
    23         print('Exception',e)
    24 
    25     else:
    26         print('else')
    27 
    28     finally:
    29         print('....')
    30 #--------------------------------------------

        写异常时,先 except ‘小弟’,后写‘大哥’,else 后面是没有捕捉到错误时执行,finally 后是无论如何都会执行。

      主动抛出异常

    1 try:
    2     raise Exception('我是主动抛出的异常')  # 主动触发异常
    3 except Exception as e:
    4     print(e)
    5     # 执行结果:我是主动抛出的异常

      主动触发异常的小应用(记录错误日志)

     1 def db():
     2    #return True
     3     return False
     4 
     5 def index():
     6     try:
     7         result = db()
     8         if not result:
     9             #打开文件,写日志
    10             raise Exception('数据库处理错误')  #当数据库返回值为False时,主动抛出异常,记录日志。
    11 
    12     except Exception as e:
    13         str_error = str(e)
    14         print(str_error)
    15         #打开文件写日志
    16         
    17 index()

      自定义异常

     1 class LfdError(Exception):
     2 
     3     def __init__(self,msg):
     4         self.message = msg
     5 
     6     def __str__(self):
     7         return self.message
     8 
     9 obj = LfdError('liufeiduo')
    10 print(obj)
    11 
    12 try:
    13     raise LfdError('我错了')
    14 except LfdError as e:
    15     print(e)

      断言  assert + 条件  如果满足条件,继续执行,若不满足条件,直接报错。用于强制用户服从,不服从就报错,可捕获但一般不捕获。

      5. 反射

        在Python 中执行反射效率蛮高的。

      通过字符串的形式操作对象中的成员:

        ①getattr方法,到某某东西中获取某某内容。

     1 class Foo:
     2     def __init__(self,name,age):
     3         self.name = name
     4         self.age = age
     5 
     6     def show(self):
     7         return "%s-%s" %(self.name,self.age)
     8 object = Foo('liufeiduo',22)
     9 
    10 # b = "name"
    11 # print(object.__dict__[b])
    12 inp = input('>>>>>>>>>>')
    13 #去什么东西里面获取什么内容
    14 b = getattr(object,inp)
    15 
    16 print(b)    #liufeiduo

        ②hasattr方法,去检测对象中是否有某成员,返回True、False。

        ③setattr方法,在对象中主动设置某个值。

     1 class Foo:
     2     def __init__(self,name,age):
     3         self.name = name
     4         self.age = age
     5 
     6     def show(self):
     7         return "%s-%s" %(self.name,self.age)
     8 object = Foo('liufeiduo',22)
     9 
    10 
    11 setattr(object,'love','chengjunfei')
    12 print(object.love)  #chengjunfei

        ④delattr方法,将主动设置的某个值删除掉。

        反射在模块之间也是可以用的。

      6.单例模式

    class Foo:
    
        __v = None
    
        @classmethod
        def get_instance(cls):
            if cls.__v:
                return cls.__v
    
            else:
                cls.__v = Foo()
                return cls.__v
    
    object1 = Foo.get_instance()
    print(object1)
    object2 = Foo.get_instance()
    print(object2)
    
    #          执行结果:
    #<__main__.Foo object at 0x000001137E007908>
    #<__main__.Foo object at 0x000001137E007908>

      好处:内存中对象只创建一份就可以了。

  • 相关阅读:
    数组从文件中读取(接上问题)
    符合json格式要求的字符串转化为json字符串
    json-lib --->入门
    XStream-->别名;元素转属性;去除集合属性(剥皮);忽略不需要元素
    Ajax案例5-->省市联动
    Ajax案例4-->接收后台传递的XML数据
    Ajax案例3-->判断用户名是否被占用
    Ajax案例2-->POST请求
    Ajax案例1-->GET请求
    SecureCRT连接VMWare中的linux系统相关配置
  • 原文地址:https://www.cnblogs.com/jinzejun/p/9004799.html
Copyright © 2020-2023  润新知