博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 08 面向对象
阅读量:6251 次
发布时间:2019-06-22

本文共 13963 字,大约阅读时间需要 46 分钟。

Python 面向对象


1、编程范式

2、面向对象特性

3、属性、方法

4、三大特性

5、高级方法

6、类的特殊成员方法

7、反射

8、异常处理

9、单例模式


一、编程范式 

编程:程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 

面向过程编程(Procedural Programming)

面向过程编程依赖:procedures,一个procedure包含一组要被进行计算的步骤,面向过程又被称为top-down languages, 就是程序从上到下一步步执行。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。这样做的问题也是显而易见的,就是如果你要对程序进行修改,对你修改的那部分有依赖的各个部分你都也要跟着修改,所以我们一般认为, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护 的, 那还是用面向对象最方便了。

面向对象编程(Object-Oriented Programming )

面向对象编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

二、面向对象的特性

类:class,一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法

对象 :object,一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性

封装:Encapsulation,在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法

继承:Inheritance ,一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承

多态:Polymorphism ,多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。

三、属性、方法

 1、属性、方法、类变量、实例变量

1 class dog: #dog:类名 2     n = 123    #类变量 3     def __init__(self,name): 4         #构造函数 5         #在实例化时做一些类的初始化工作 6         self.name = name  #实例变量(静态属性),作用域就是实例本身 7     def bulk(self):  #类的方法(动态属性),功能 8         print("%s:wang wang wang !"% self.name) 9 10 d1 = dog("狗") #d1 叫做dog类的实例11 d1.bulk()
基本属性

2、构造函数、析构函数、私有方法、私有属性

1 #析构函数:在实例释放、销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库连接打开的临时文件 2 class dog: #dog:类名 3     def __init__(self,name,age = 0): 4         #构造函数 5         #在实例化时做一些类的初始化工作 6         self.name = name 7         self.__age = age  #私有属性:只能在内部访问和修改(私有方法同理也是在函数前面加两个_) 8     def show_age(self): 9         print("name:%s age:%s"%(self.name,self.__age))10     def after_year(self):11         self.__age += 112         print("一年过去了。。。")13     def __del__(self):  #析构函数14         print(self.name)15 r1 = dog("哈士奇")16 r1.after_year()17 r1.show_age()
View Code

四、特性

1、封装

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容

将内容封装到某处:

1 class foo: #类名2     def __init__(self,name,age):3         self.name = name4         self.age = age5 pop1 = foo("zz",12)6 pop2 = foo("aa",13)7 # foo相当于一类事物的模板,当执行pop1 = foo("zz",12)时8 # 相当于在foo中:self = poo1,pop1 = foo("zz",12) 即 pop1 = foo(por1,"zz",12)9 # 将类中的内容封装到了对象 pop1中,而pop1有了自己的name 和 age 属性并在内存中保存了下来
封装

从某处调用被封装的内容

class foo: #类名    def __init__(self,name,age):        self.name = name        self.age = agepop1 = foo("zz",12)print(pop1.name,pop1.age)  #通过对象直接调用
通过对象直接调用
1 class foo: #类名2     def __init__(self,name,age):3         self.name = name4         self.age = age5     def detail(self):6         print(self.name,self.age)7 pop1 = foo("zz",12)8 pop1.detail() #通过self间接调用
通过self间接调用

2、继承

继承:面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容

所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法

class People:    def __init__(self,name,age):        self.name = name        self.age = age    def eat(self):        print("%s is eating..."%self.name)    def talk(self):        print("%s is talking..."%self.name)    def sleep(self):        print("%s is sleeping..."%self.name)class man(People):    def __init__(self,name,age,money):        # People.__init__(self,name,age)  #重构父类构造函数        super(man,self).__init__(name,age)        self.money = money    def drink(self):        print("%s is drinking..."%self.name)    def sleep(self):        People.sleep(self)   #重构父类方法        print("man is sleeping...")class woman(People):    def makeup(self):        print("%s is makeuping..."%self.name)m1 = man("zz",12,1)m1.drink()m1 .sleep()m2 = woman("aa",10)
简单继承

多继承:

1、Python的类可以继承多个类,Java和C#中则只能继承一个类

1 # 经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法 2 # 从写法上区分的话,如果当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类 3 #class People:  #经典类 4 class People(object):   #新式类 5     def __init__(self,name,age): 6         self.name = name 7         self.age = age 8     def eat(self): 9         print("%s is eating..."%self.name)10     def talk(self):11         print("%s is talking..."%self.name)12     def sleep(self):13         print("%s is sleeping..."%self.name)14 class relation(object):15     def make_friend(self,obj):16         print("%s is making friend with %s"%(self.name,obj.name))17 18 class man(People,relation):19     def __init__(self,name,age,money):20         # People.__init__(self,name,age)  #重构父类构造函数21         super(man,self).__init__(name,age)22         self.money = money23     def drink(self):24         print("%s is drinking..."%self.name)25     def sleep(self):26         People.sleep(self)   #重构父类方法27         print("man is sleeping...")28 class woman(People,relation):29     def makeup(self):30         print("%s is makeuping..."%self.name)31 32 m1 = man("zz",12,1)33 w1 = woman("aa",10)34 m1.make_friend(w1)
多继承

2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

  

#经典类多继承:深度优先class D:    def bar(self):        print ('D.bar')class C(D):    def bar(self):        print ('C.bar')class B(D):    def bar(self):        print ('B.bar')class A(B, C):    def bar(self):        print ('A.bar')a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> D --> C# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()#新式类多继承:广度优先class D(object):    def bar(self):        print ('D.bar')class C(D):    def bar(self):        print ('C.bar')class B(D):    def bar(self):        print ('B.bar')class A(B, C):    def bar(self):        print ('A.bar')a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> C --> D# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()# 经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错# 新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错# 在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
py2版本多继承寻找方式

从py3开始全部都是广度优先,没有深度优先

3、多态

 Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚“鸭子类型”。

多态的作用是实现接口的重用

1 class Animal(object): 2     def __init__(self, name):  # Constructor of the class 3         self.name = name 4     def talk(self):              # Abstract method, defined by convention only 5         raise NotImplementedError("Subclass must implement abstract method") 6  7 class Cat(Animal): 8     def talk(self): 9         print('%s: 喵喵喵!' %self.name)10 11 class Dog(Animal):12     def talk(self):13         print('%s: 汪!汪!汪!' %self.name)14 # c1 = Cat('猫')15 # c1.talk()16 # d1 = Dog('狗')17 # d1.talk()18 # 为采用多态19 def anmiaml(obj): #一个接口,多种形态20     obj.talk()21 c1 = Cat('猫')22 d1 = Dog('狗')23 anmiaml(c1)24 anmiaml(d1)
多态

 五、高级方法

1、静态方法

只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性

1 class dog(object): 2     def __init__(self,name): 3         self.name = name 4     @staticmethod  #加上之后下面的方法和类就没有关系了 5     def eat(self): 6         print("%s is eating %s"%(self.name,"骨头")) 7 # 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法 8 # 可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量 9 # 但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了10 # 它与类唯一的关联就是需要通过类名来调用这个方法11 d = dog("狗")12 # d.eat("骨头")  未加@staticmethod时的调用13 d.eat(d)
静态方法

2、类方法

只能访问类变量,不能访问实例变量

1 class dog(object): 2     name = "gou" 3     def __init__(self,name): 4         self.name = name 5     @classmethod 6     def eat(self): 7         print("%s is eating %s"%(self.name,"骨头")) 8     def talk(self): 9         print("%s is talking.."%self.name)10 d = dog("狗")11 d.eat()  #gou is eating 骨头  输出内容为类变量参数而非实例变量参数
类方法

3、属性方法

把一个方法变成一个静态属性

1 class dog(object): 2     name = "gou" 3     def __init__(self,name): 4         self.name = name 5         self.__food = "骨头" 6     @property  #把一个方法变成静态属性 7     def eat(self): 8         print("%s is eating %s"%(self.name,self.__food)) 9     @eat.setter     #给静态属性传参数10     def eat(self,food):11         print("set to food:",food)12         self.__food = food13     @eat.deleter14     def eat(self):15         del self.__food16         print("删除私有food!")17     def talk(self):18         print("%s is talking.."%self.name)19 d = dog("狗")20 d.eat  #只能按照静态属性调用方式调用不能传参数,也不能d.eat()21 d.eat = "狗粮"  #给静态属性传参数22 d.eat   #狗 is eating 狗粮23 del d.eat24 d.eat  #报错
属性方法

六、类的特殊成员方法

1 class dog(object): 2     '''描述狗这个对象''' 3     '''写类的时候一定写上这个类是作什么用的''' 4     name = "gou" 5     def __init__(self,name): 6         self.name = name 7     def eat(self): 8         print("%s is eating.."%self.name) 9     def talk(self):10         print("%s is talking.."%self.name)11     def __call__(self, *args, **kwargs):12         print("run in call..",args,kwargs)13     def __str__(self):14         return "
"%self.name15 # 1、 __doc__ 输出:类的描述信息16 print(dog.__doc__) #输出:类的描述信息 (描述狗这个对象)17 # 2、__module__ 表示当前操作的对象在那个模块18 # 3、__class__ 表示当前操作的对象的类是什么19 print(dog.__module__) #__main__ 如果这个类是import的则会返回这个类所在模块的目录20 print(dog.__class__) #
输出这个类本身21 # 4、__init__ 构造方法,通过类创建对象时,自动触发执行22 # 5、__del__ 析构方法,当对象在内存中被释放时,自动触发执行23 # 6、__call__ 对象后面加括号,触发执行24 d = dog("狗")25 d(1,2,3,name = 321) #输出:run in call.. (1, 2, 3) {'name': 321}26 # 7、__dict__ 查看类或对象中的所有成员27 print(dog.__dict__) #以一个字典的形式把类中的方法属性全部打印,不包括实例属性28 print(d.__dict__) #输出:{'name': '狗'} 打印所有实例属性,不包括类属性29 # 8、__str__ 如果一个类中定义了__str__方法,那么在打印 对象时,默认输出该方法的返回值30 print(d) #输出:
31 # 9、__getitem__、__setitem__、__delitem__ 用于索引操作,如字典。分别表示获取、设置、删除数32 class Foo(object):33 def __getitem__(self, key):34 print('__getitem__',key)35 def __setitem__(self, key, value):36 print('__setitem__',key,value)37 def __delitem__(self, key):38 print('__delitem__',key)39 obj = Foo()40 result = obj['k1'] # 自动触发执行 __getitem__41 obj['k2'] = 'zz' # 自动触发执行 __setitem__42 del obj['k1'] # 自动触发执行 __delitem__43 # 10、__new__ \ __metaclass__44 class Foo(object):45 def __init__(self,name):46 self.name = name47 f = Foo("zz")48 print(type(f)) #
表示,obj 对象由Foo类创建49 print(type(Foo)) #
表示,Foo类对象由 type 类创建50 # 即:Foo是通过type类的构造方法创建51 # 创建类就可以有两种方式52 # 普通方式53 class Foo(object):54 def func(self):55 print("in Foo!")56 #特殊方式57 def func(self):58 print("in func!")59 foo = type('foo',(object,), {
'func': func})60 #type第一个参数:类名61 #type第二个参数:当前类的基类62 #type第三个参数:类的成员63 # 类 是由 type 类实例化产生64 # 类默认是由 type 类实例化产生,type类中如何实现的创建类:65 # 类中有一个属性 __metaclass__,其用来表示该类由谁来实例化创建,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看类创建的过程。66 # 类的生成调用顺序依次是 __new__ --> __init__ --> __call__
特殊成员方法

七、反射

通过字符串映射或修改程序运行时的状态、属性、方法

1 def bulk(self): 2     print("%s is bulking..."%self.name) 3 class Dog(object): 4     def __init__(self,name): 5         self.name = name 6     def eat(self): 7         print("%s is eating..."%self.name) 8  9 d = Dog("狗")10 choice = input(">>:").strip()11 #输入eat12 print(hasattr(d,choice)) #True13 #hasattr(obj,name_str) 判断一个对象obj里是否有对应的name_str字符串的方法映射14 # print(getattr(d,choice)) #
> 内存对象15 #getattr(obj,name_str) 根据字符串去获取obj对象里的对应的方法的内存地址16 if hasattr(d,choice):17 func = getattr(d,choice)18 func()19 else:20 setattr(d,choice,bulk)21 d.bulk(d)22 #setattr(obj,'y',z) 通过字符串设置新的方法23 #delattr24 delattr(d,choice)
反射

 八、异常处理

1、介绍

在编程过程中为了增加友好性,在程序出现报错时一般不会将错误信息显示给用户,而是显示一个提示的页面。

1 name = []2 dir = {}3 try:4     dir["aa"]5     name[2]6 except KeyError as e:7     print("没有这个key:",e)8 except IndexError as e:9     print("列表操作错误:",e)
简单语法
1 name = [] 2 dir = {} 3 try: 4     dir["aa"] 5     name[2] 6     open('zz.txt') 7 except KeyError as e: 8     print("没有这个key:",e) 9 except IndexError as e:10     print("列表操作错误:",e)11 # except (KeyError,IndexError) as e: #一般不这么写,这样不知道是哪个触发的12 except Exception as e: #抓住所有错误13 #对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行14     print(e)15 else:16     print("一切正常!") #如果程序没有任何错误走这里17 finally:18     print("不管有没有错都执行!")
异常处理写法

2、异常种类

#常用异常:'''AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError 输入/输出异常;基本上是无法打开文件ImportError 无法引入模块或包;基本上是路径问题或名称错误IndentationError 语法错误(的子类) ;代码没有正确对齐IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]KeyError 试图访问字典里不存在的键KeyboardInterrupt Ctrl+C被按下NameError 使用一个还未被赋予对象的变量SyntaxError Python代码非法,代码不能编译TypeError 传入对象类型与要求的不符合UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它ValueError 传入一个调用者不期望的值,即使值的类型是正确的''''''其他异常:ArithmeticErrorAssertionErrorAttributeErrorBaseExceptionBufferErrorBytesWarningDeprecationWarningEnvironmentErrorEOFErrorExceptionFloatingPointErrorFutureWarningGeneratorExitImportErrorImportWarningIndentationErrorIndexErrorIOErrorKeyboardInterruptKeyErrorLookupErrorMemoryErrorNameErrorNotImplementedErrorOSErrorOverflowErrorPendingDeprecationWarningReferenceErrorRuntimeErrorRuntimeWarningStandardErrorStopIterationSyntaxErrorSyntaxWarningSystemErrorSystemExitTabErrorTypeErrorUnboundLocalErrorUnicodeDecodeErrorUnicodeEncodeErrorUnicodeErrorUnicodeTranslateErrorUnicodeWarningUserWarningValueErrorWarningZeroDivisionError'''
异常

 3、自定义异常

1 class My_Exception(Exception):2     def __init__(self, msg):3         self.message = msg4 try:5     raise My_Exception('我的异常')  #主动触发异常6 except My_Exception as e:7     print(e)8
自定义异常

 九、单例模式

1 #单例模式:永远用一个实例的模式 2  3 # class Foo(object): 4 #     instance = None 5 # 6 #     def __init__(self): 7 #         self.name = 'alex' 8 #     @classmethod 9 #     def get_instance(cls):10 #         if Foo.instance:11 #             return Foo.instance12 #         else:13 #             Foo.instance = Foo()14 #             return Foo.instance15 #16 #     def process(self):17 #         return '123'18 19 # obj1 = Foo()20 # obj2 = Foo()21 # print(id(obj1),id(obj2))22 23 #low的单例模式24 # obj1 = Foo.get_instance()25 # obj2 = Foo.get_instance()26 # print(id(obj1),id(obj2))27 28 29 #基于new方法实现单例模式30 class Foo(object):31     instance = None32 33     def __init__(self):34         self.name = 'alex'35 36     def __new__(cls, *args, **kwargs):37         if Foo.instance:38             return Foo.instance39         else:40              Foo.instance = object.__new__(cls, *args, **kwargs)41              return Foo.instance42 43 # obj1 = Foo()44 # obj2 = Foo()45 # print(id(obj1),id(obj2))
单例模式

 

转载于:https://www.cnblogs.com/hy0822/p/9169201.html

你可能感兴趣的文章
遍历文件夹
查看>>
js和html标签的混合使用
查看>>
生成不重复随机数
查看>>
Kinect for Windows SDK 1.5 的改进及新特性
查看>>
jQuery-倒计时
查看>>
expect语法基础: while、for 循环、if 语句的用法示例
查看>>
ubuntu 9.04 的 NTFS 分区自动加载
查看>>
现代软件工程讲义 7 设计阶段 Spec
查看>>
精确控制MFC控件窗口的位置和大小(top|left|width|height)
查看>>
ASP.NET MVC中Areas的namespaces和UseNamespaceFallback
查看>>
队列希望IOS开发(66)之构建自己的分派队列
查看>>
谈谈Android中的SurfaceTexture
查看>>
Nginx+Varnish又开始新的征程了
查看>>
NUnit-Console 命令行选项详解
查看>>
[问题2014S10] 解答
查看>>
微信游戏《全民炫舞》公司的引擎开发和布料系统技术介绍
查看>>
同步与互斥的区别和联系
查看>>
eclipse中tomcat能正常启动,在浏览器中不能打开问题
查看>>
基于Linux根据僵尸网络病毒平台《比尔盖茨》
查看>>
JNI编程(二) —— 让C++和Java相互调用(2)
查看>>