zoukankan      html  css  js  c++  java
  • Python之面向对象

    1.面向对象相关的几个名词

      类:具有相同特征的一类事物。

      对象:也就是实例,具体的事物,例如动物类,那么猫就是对象,具体的实例。

      实例化:创建对象的过程,类---->对象。

    类的三要素:

      类名:类事物的名字。

      属性:类事物具体的特征。

      方法:类事物具体的行为。

    2.定义类

      类名的命名规则要符合大驼峰命名法,格式如下:

    class 类名:

      def 方法1(self,参数列表):

        pass

      def 方法2(self,参数列表):

        pass

     1 class Animal:
     2 
     3     def eat(self,name):
     4         print("%s会吃"% name)
     5 
     6     def run(self,name):
     7         print("%s会跑"% name)

    3.创建对象

      对象变量 = 类名(),调用有参数的方法即可。

     1 class Animal:
     2 
     3     def eat(self):
     4         print("会吃")
     5 
     6     def run(self):
     7         print("会跑")
     8 
     9 tom = Animal()
    10 tom.eat()
    11 tom.run()
    12 结果:
    13 会吃
    14 会跑
    View Code

    4.初始化方法

      当一个对象创建后,会自动执行以下操作:

        为对象在内存中分配空间。

        为对象的属性设置初始值。

        同时__init__方法被自动调用。

     1 class Animal:
     2 
     3     def __init__(self):
     4         self.name = "汤姆"
     5         self.age = "2岁"
     6         print("检测是否被自动调用...")
     7 
     8     def eat(self):
     9         print("会吃")
    10 
    11     def run(self):
    12         print("会跑")
    13 
    14 tom = Animal()
    15 print(tom)
    16 print(tom.name)
    17 print(tom.age)
    18 结果:
    19 检测是否被自动调用...
    20 <__main__.Animal object at 0x0000013AB6F04160>
    21 汤姆
    22 2岁
    View Code

    5.__init__方法内部定义属性

      上述定义的属性过于死板,可传入形参,此时在创建方法时直接传入属性值即可,且在对象内部可直接访问的对象的属性。

     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6 
     7     def eat(self):
     8         print("会吃")
     9 
    10     def run(self):
    11         print("会跑")
    12 
    13 tom = Animal("汤姆","2岁")
    14 print(tom.name,tom.age)
    15 结果:
    16 汤姆 2岁
    View Code

      属性可以在类的外部设置,但是如果调用属性在设置前面,则会报错,故不建议在类的外部设置类的属性。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("会吃")
     8 
     9     def run(self):
    10         print("会跑")
    11 
    12 tom = Animal("汤姆")
    13 print(tom.name)
    14 # print(tom.age) #结果:AttributeError: 'Animal' object has no attribute 'age'
    15 tom.age = "2岁"
    16 print(tom.age)
    17 结果:
    18 汤姆
    19 2岁
    View Code

      在对象方法内部,可以访问对象的属性。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12 tom = Animal("汤姆")
    13 tom.eat()
    14 tom.run()
    15 结果:
    16 汤姆会吃
    17 汤姆会跑
    View Code

      同一个类创建的多个对象之间,属性互不干扰。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12 jerry = Animal("杰瑞")
    13 tom = Animal("汤姆")
    14 tom.eat()
    15 tom.run()
    16 jerry.eat()
    17 jerry.run()
    18 结果:
    19 汤姆会吃
    20 汤姆会跑
    21 杰瑞会吃
    22 杰瑞会跑
    View Code

      一个对象的属性可以是另一个类创建的对象。

     1 class Animal:
     2 
     3     def __init__(self,name,cat_lihua):
     4         self.name = name
     5         self.cat_type = cat_lihua
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12 class Type_cat:
    13 
    14     def __init__(self,name):
    15         self.name = name
    16 
    17     def catch(self):
    18         print("%s是%s,会抓老鼠..."%(tom.name,self.name))
    19 
    20 cat_lihua = Type_cat("狸花猫")
    21 tom = Animal("汤姆",cat_lihua)
    22 tom.cat_type.catch()
    23 结果:
    24 汤姆是狸花猫,会抓老鼠...
    View Code

    6.__del__方法

      当一个对象被从内存中销毁前,会自动调用__del__方法,del 对象名,可以删除一个对象。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12     def __del__(self):
    13         print("检测是否有调用...")
    14 
    15 tom = Animal("汤姆")
    16 print("abc")
    17 del tom  #删除 tom对象时,立即执行了 __del__方法...
    18 print("123")
    19 结果:
    20 abc
    21 检测是否有调用...
    22 123
    View Code

      __del__是对象在生命周期内调用的最后一个方法,如果对一个对象在销毁前有需求,可以使用。

    7.__str__方法

      当print(对象名)时,默认情况下,会显示的是对象的类,以及以十六进制表示的内存中的地址,而__str__方法就是自定义print(对象名)现实的内容,此方法返回的必须是字符串。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12     def __del__(self):
    13         print("检测是否有调用...")
    14 
    15     def __str__(self):
    16         return "检测print(对象名)是否自定义修改..."
    17 
    18 tom = Animal("汤姆")
    19 print(tom)
    20 结果:
    21 检测print(对象名)是否自定义修改...
    View Code

    8.继承

      子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发。

      子类中应该根据职责,封装子类特有的属性和方法。

      继承的传递性,即子类不仅拥有父类的方法和属性,还拥有父类的父类的属性和方法。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12     def __str__(self):
    13         return "检测print(对象名)是否自定义修改..."
    14 
    15 class Cat(Animal):
    16 
    17 
    18     def catch(self):
    19         print("会抓老鼠...")
    20 
    21 tom = Cat("汤姆")
    22 tom.eat() #Cat类继承自父类Animal的方法
    23 tom.run() #Cat类继承自父类Animal的方法
    24 tom.catch() #Cat类特有方法
    25 结果:
    26 汤姆会吃
    27 汤姆会跑
    28 会抓老鼠...
    View Code

    9.方法的重写

      当父类的方法实现不能满足子类需求时,可以对方法进行重写。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12 
    13 class Cat(Animal):
    14 
    15     def catch(self):
    16         print("会抓老鼠...")
    17 
    18     def eat(self):
    19         print("%s吃鱼"% tom.name)
    20 
    21 tom = Cat("汤姆")
    22 tom.eat()
    23 结果:
    24 汤姆吃鱼
    View Code

      当父类的方法同样有需求,但还有其他需求时,可调用父类的方法的同时,再进行扩展。

     1 class Animal:
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     def eat(self):
     7         print("%s会吃"% self.name)
     8 
     9     def run(self):
    10         print("%s会跑"% self.name)
    11 
    12 
    13 class Cat(Animal):
    14 
    15     def catch(self):
    16         print("会抓老鼠...")
    17 
    18     def eat(self):
    19         super().eat()
    20         print("%s吃鱼"% tom.name)
    21 
    22 tom = Cat("汤姆")
    23 tom.eat()
    24 结果:
    25 汤姆会吃
    26 汤姆吃鱼
    View Code

    10.私有属性和方法

      私有属性、方法就是对象不希望公开的属性、方法,在属性名和方法名前加两个下划线,定义的就是私有属性或方法,在类的外部无法访问,在对象的方法内部可以访问。

     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.__age = age
     6 
     7     def eat(self):
     8         print("%s会吃"% self.name)
     9 
    10     def __run(self):
    11         print("%s会跑"% self.name)
    12 
    13 tom = Animal("汤姆","2岁")
    14 print(tom.name)
    15 # print(tom.age) #结果:AttributeError: 'Animal' object has no attribute 'age'
    16 tom.eat()
    17 # tom.run() #结果:AttributeError: 'Animal' object has no attribute 'run'
    18 结果:
    19 汤姆
    20 汤姆会吃
    View Code

      子类对象不能在自己的方法内部,直接访问父类的私有属性或方法,可以在自己的内部访问父类的共有属性和公有方法。

     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.__age = age
     6 
     7     def eat(self):
     8         print("%s会吃"% self.name)
     9 
    10     def __run(self):
    11         print("%s会跑"% self.name)
    12 
    13 class Cat(Animal):
    14 
    15     def catch(self):
    16         print("%s是狸花猫..."% self.name)
    17         # print("%s%s了"%(self.name,self.age)) #结果:AttributeError: 'Cat' object has no attribute 'age'
    18 
    19 tom = Cat("汤姆","2岁")
    20 tom.catch()
    21 tom.eat()
    22 # tom.__run() #结果:AttributeError: 'Cat' object has no attribute '__run'
    23 结果:
    24 汤姆是狸花猫...
    25 汤姆会吃
    View Code

      父类内部可以调用自己的私有属性和方法,子类可以调用父类的公有属性和方法,所以我们可以间接调用父类的私有属性和方法。即我们在父类的公有方法中调用其私有方法,子类中调用父类公有方法,从而达到调用父类私有方法的目的。

     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.__age = age
     6 
     7     def eat(self):
     8         print("%s会吃"% self.name)
     9 
    10     def __run(self):
    11         print("%s会跑"% self.name)
    12 
    13     def run(self):
    14         self.__run()
    15         print("%s%s了"%(self.name,self.__age))
    16 
    17 
    18 class Cat(Animal):
    19 
    20     def catch(self):
    21         print("%s是狸花猫..."% self.name)
    22 
    23 tom = Cat("汤姆","2岁")
    24 tom.run()
    25 结果:
    26 汤姆会跑
    27 汤姆2岁了
    View Code

    11.多继承

      子类可以拥有多个父类,并且具有所有父类的属性和方法,尽量避免父类之间出现同名的属性和方法。

     1 class A:
     2 
     3     def foo(self):
     4         print("fool A...")
     5 
     6     def bar(self):
     7         print("bar A...")
     8 
     9 
    10 class B:
    11 
    12     def foo(self):
    13         print("fool B...")
    14 
    15     def bar(self):
    16         print("bar B...")
    17 
    18 
    19 class C(A,B):
    20     pass
    21 
    22 cc = C()
    23 cc.foo()
    24 cc.bar()
    25 结果:
    26 fool A...
    27 bar A...
    28 
    29 
    30 ----------分割线-----------
    31 class A:
    32 
    33     def foo(self):
    34         print("fool A...")
    35 
    36     def bar(self):
    37         print("bar A...")
    38 
    39 
    40 class B:
    41 
    42     def foo(self):
    43         print("fool B...")
    44 
    45     def bar(self):
    46         print("bar B...")
    47 
    48 
    49 class C(B,A):
    50     pass
    51 
    52 cc = C()
    53 cc.foo()
    54 cc.bar()
    55 结果:
    56 fool B...
    57 bar B...
    View Code

      当拥有多个父类,且具有相同方法和属性时,调用时不易区分调用的是哪个父类的方法,可用__mro__方法搜素查找调用父类方法的顺序。

    12.新式类和经典类

      新式类:以object为基类的是新式类,具有object类的内置封装的方法,推荐使用。
      经典类:不以object为基类的类。

    13.多态

      不同的子类对象调用相同的父类方法,产生不同的执行结果,多态是以继承和重写父类方法为前提下,同一个方法会产生不同的形态。

    14.类属性

      在类中定义属性,通常用来记录与类有关的特征,类属性不会记录具体对象的特征。

    有两种访问方法:

      类名.属性名

      对象名.属性名  (不推荐使用)

     1 class Animal:
     2     count = 0
     3 
     4     def __init__(self,name,age):
     5         self.name = name
     6         self.age = age
     7         Animal.count += 1
     8 
     9     def eat(self):
    10         print("%s贼贪吃..."% self.name)
    11 
    12 dog = Animal("金毛","1岁")
    13 cat = Animal("汤姆","2岁")
    14 print(Animal.count)
    15 print(dog.count)
    16 print(cat.count)
    17 结果:
    18 2
    19 2
    20 2
    View Code

      两种方法仅仅访问时,都能达到效果。但是当用 对象名.属性名 访问方法给类属性赋值时,会在对象中重新创建一个与类属性名相同的 对象属性,并且将值赋予对象属性,故不推荐使用。

     1 class Animal:
     2     count = 0
     3 
     4     def __init__(self,name,age):
     5         self.name = name
     6         self.age = age
     7         Animal.count += 1
     8 
     9     def eat(self):
    10         print("%s贼贪吃..."% self.name)
    11 
    12 dog = Animal("金毛","1岁")
    13 cat = Animal("汤姆","2岁")
    14 cat.count = 10
    15 print(Animal.count)
    16 print(dog.count)
    17 print(cat.count)
    18 结果:
    19 2
    20 2
    21 10
    View Code

    15.类方法

      如果一个方法内部值需要访问类属性时,即可定义成类方法。

    语法格式:

    @classmethod

    def 类方法名(cls):

      pass

     1 class Animal:
     2     count = 0
     3 
     4     def __init__(self,name,age):
     5         self.name = name
     6         self.age = age
     7         Animal.count += 1
     8 
     9     def eat(self):
    10         print("%s贼贪吃..."% self.name)
    11 
    12     @classmethod
    13     def obj_num(cls):
    14         print("创建的对象数:%s"%Animal.count)
    15 
    16 dog = Animal("金毛","1岁")
    17 cat = Animal("汤姆","2岁")
    18 Animal.obj_num()
    19 cat.obj_num()
    20 结果:
    21 创建的对象数:2
    22 创建的对象数:2
    View Code

    16.静态方法

      如果一个方法内部既不需要访问实例属性或者调用实例方法,也不需要访问类属性或者调用类方法,此时,可以把这个方法封装成一个静态方法。

    @staticmethod

    def 静态方法():

      pass

      调用静态方法时不用创建对象,通过 类名.静态方法名() 调用即可。

     1 class Animal:
     2     count = 0
     3 
     4     def __init__(self,name,age):
     5         self.name = name
     6         self.age = age
     7         Animal.count += 1
     8 
     9     def eat(self):
    10         print("%s贼贪吃..."% self.name)
    11 
    12     @classmethod
    13     def obj_num(cls):
    14         print("创建的对象数:%s"%cls.count)
    15 
    16     @staticmethod
    17     def fun():
    18         print("静态方法...")
    19 
    20 Animal.fun()
    21 结果:
    22 静态方法...
    View Code

    17.单例模式

      目的:让类在创建对象时,系统中只存在唯一的一个实例,即每次执行时,返回对象的地址都是相同的。

      正常情况,每创建一个对象,其地址都是不同的。

     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6 
     7 cat = Animal("汤姆","2岁")
     8 dog = Animal("二哈","1岁")
     9 print(cat)
    10 print(dog)
    11 结果:
    12 <__main__.Animal object at 0x000001C3BDAA9550>
    13 <__main__.Animal object at 0x000001C3BDAB42B0>
    View Code

    1)__new__方法

      我们知道,当创建一个对象时,python解释器会自动执行两个方法,__new__方法为对象分配空间,__init__方法初始化对象。

      __new__方法是一个静态方法,为对象在内存中分配空间,并且返回对象的引用。

    2)重写__new__方法

      重写时,要调用父类方法,赋值给一个变量,再将变量返回。固定的代码。

    1 instance = None
    2 def __new__(cls, *args, ""kwargs):
    3     if isstance is None:
    4         cls.instance = super().__new__(cls)
    5     return cls.instance
     1 class Animal:
     2 
     3     def __init__(self,name,age):
     4         self.name = name
     5         self.age = age
     6         print("检测__init__方法调用次数...")
     7 
     8     instance = None
     9 
    10     def __new__(cls, *args, **kwargs):
    11         if cls.instance is None:
    12             cls.instance = super().__new__(cls)
    13         return cls.instance
    14 
    15 cat = Animal("汤姆","2岁")
    16 dog = Animal("二哈","1岁")
    17 print(cat)
    18 print(dog)
    19 结果:
    20 检测__init__方法调用次数...
    21 检测__init__方法调用次数...
    22 <__main__.Animal object at 0x0000021187C84160>
    23 <__main__.Animal object at 0x0000021187C84160>
    View Code

      重写__new__方法后,不管创建多少个对象,返回的地址都是创建的第一个对象的地址,但是__init__方法每创建一个对象会初始化一次。我们可以设置一个 类属性,将False 赋值给他,然后在__init__方法内用if判断,如果为False则执行初始化方法,执行后将类属性的值改为True,再次调用__init__方法时就不会被多次执行。

     1 class Animal:
     2 
     3     init_fun = False
     4 
     5     def __init__(self,name,age):
     6         if Animal.init_fun is False:
     7             self.name = name
     8             self.age = age
     9             print("检测__init__方法调用次数...")
    10             Animal.init_fun = True
    11         return
    12 
    13     instance = None
    14 
    15     def __new__(cls, *args, **kwargs):
    16         if cls.instance is None:
    17             cls.instance = super().__new__(cls)
    18         return cls.instance
    19 
    20 cat = Animal("汤姆","2岁")
    21 dog = Animal("二哈","1岁")
    22 print(cat)
    23 print(dog)
    24 结果:
    25 检测__init__方法调用次数...
    26 <__main__.Animal object at 0x0000022EA09742B0>
    27 <__main__.Animal object at 0x0000022EA09742B0>
    View Code

    18.异常

      抛出异常:程序执行时遇到一个错误,会停止程序的执行,并且提示一些错误信息。

     1 try:
     2     pass
     3 except 异常类型1:
     4     pass
     5 except 异常类型2:
     6     pass
     7 except Excetion as e:
     8     print("未知错误,%s",%e)
     9 else: #没有出现异常才会执行的代码
    10     pass
    11 finally:  #无论是否有异常,都会执行的代码
    12     pass

      异常类型为触发异常后抛出的异常信息中的第一个单词,用以捕捉异常。

     1 try:
     2     int_put = int(input("输入数字>>>"))
     3     num = 10 / int_put
     4     print(num)
     5 except ValueError:
     6     print("输入错误的值,请输入数字>>>")
     7 except ZeroDivisionError:
     8     print("除数为0错误...")
     9 except Exception as e:
    10     print("未知错误,%s"%e)
    11 else:
    12     print("没有出现异常才会执行的代码")
    13 finally:
    14     print("无论是否有异常,都会执行的代码")
    15 结果:
    16 输入数字>>>10
    17 1.0
    18 没有出现异常才会执行的代码
    19 无论是否有异常,都会执行的代码
    20 
    21 ------------结果分割线
    22 
    23 结果:
    24 输入数字>>>0
    25 除数为0错误...
    26 无论是否有异常,都会执行的代码
    View Code

    1)异常的传递

      为了让程序能够正常运行,方法中都应该有异常处理,但是如果每个方法都写入异常处理的代码,太繁琐。事实上,当函数/方法执行 出现异常,会将异常传递给函数/方法的调用一方,如果传递到主程序,仍然没有异常处理,程序才会被终止。即异常具有传递性,所以,当我们再主程序中增加异常处理,就不用每个方法中都增加。

    2)主动抛出异常

      根据业务需求,会有主动抛出异常的情况,python中提供了Exception类。

    1 ex = Exception("xx错误") #创建异常对象,括号内可以用错误信息作为参数
    2 raise ex #主动抛出异常

      主动抛出异常类似于执行了错误代码,要与捕捉异常一起使用。

  • 相关阅读:
    21 情态动词
    20 动词的用法
    19 完成时/现在完成时和过去完成时的区别
    18 将来时
    17 一般过去时和过去进行时
    16 一般现在时和现在进行时
    15 There / Here be句型
    14 不定量表达法
    13 副词
    12 形容词
  • 原文地址:https://www.cnblogs.com/foxshu/p/12156474.html
Copyright © 2011-2022 走看看