Python 3学习 ——面向对象

Posted jinzejun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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__ 方法。

技术分享图片

 

 

 

 

 

 

 

 

 

 

 

 

  

  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>

 

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

 











以上是关于Python 3学习 ——面向对象的主要内容,如果未能解决你的问题,请参考以下文章

python之路之前没搞明白4面向对象(封装)

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

Python 3学习 ——面向对象

Python_Day7_面向对象学习

python-学习笔记1-面向对象编程