zoukankan      html  css  js  c++  java
  • python之路7:面向对象编程进阶

    1. 面向对象高级语法
    2. 异常处理

    面向对象高级语法

    经典类和新式类

    从字面上可以看出一个老一个新,新的必然包含了更多的功能,也是之后推荐的写法,从写法上区分的话,如果当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。

     

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

    • 当类是经典类时,多继承情况下,会按照深度优先方式查找
    • 当类是新式类时,多继承情况下,会按照广度优先方式查找

    经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错

    新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错

    注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了。

     类的成员

    类的成员可以分为三大类:字段、方法和属性

     注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。

    一、字段

    字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

    • 普通字段属于对象
    • 静态字段属于

    二、方法

    方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

    • 普通方法:可以在实例化后直接调用,执行普通方法时,自动将调用该方法的对象赋值给self;至少一个self参数。
    • 类方法:通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问静态字段,不能访问普通字段。至少一个参数。
    • 静态方法:通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,静态方法是不可以访问静态字段或普通字段的。不要参数。

    相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

    不同点:普通方法它的调用者不同、调用方法时自动传入的参数不同。

    三、属性

    在普通方法的基础上添加 @property 装饰器,属性仅有一个self参数,调用时,无需括号。

    四、私有成员和公有成员

    • 公有成员:在任何地方都能访问
    • 私有成员:只有在类的内部才能访问,命名时,前两个字符是下划线__
    • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
    • 私有静态字段:仅类内部可以访问;
    • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
    • 私有普通字段:仅类内部可以访问;
     1 # -*- coding:utf-8 -*-
     2 __author__ = 'BillyLV'
     3 
     4 class Province(object):
     5     # 静态字段
     6     name = '省份' #公有静态字段
     7     __name = "私有静态字段"
     8     def __init__(self, name):
     9         # 普通字段
    10         self.name = name  #公有普通字段
    11         self.__foo = "私有普通字段"
    12 
    13     def func1(self):
    14         print(Province.__name)#打印私有静态字段
    15         print(self.__foo)#打印私有普通字段
    16 
    17     def ord_func(self):
    18         """ 定义普通方法,至少有一个self参数 """
    19         print('普通方法')
    20 
    21     @property #属性
    22     def car(self):
    23         print('@property获取')
    24 
    25     @car.setter
    26     def car(self,value):
    27         print('@car.setter设置value')
    28 
    29     @car.deleter
    30     def car(self):
    31         print('@car.deleter删除')
    32 
    33     @classmethod
    34     def class_func(self):
    35         """ 定义类方法,至少有一个参数 """
    36         print('类 %s' % self.name)#只能访问类变量,即name = '省份',而不是构造方法里self.name的值了
    37 
    38     @staticmethod
    39     def static_func():
    40         """ 定义静态方法 ,无参数"""
    41         print('静态方法' )
    42 
    43 class city(Province):
    44     def func2(self):
    45         print(Province.__name)
    46         print(self.__foo)
    47 
    48 obj = Province('湖北省')
    49 
    50 obj.func1()#私有静态或普通字段仅类内部可以访问
    51 
    52 # 直接访问公有普通字段,公有普通字段需要通过对象来访问,在每个对象中都要保存一份
    53 print(obj.name)
    54 obj.ord_func()
    55 obj.class_func()
    56 obj.static_func()
    57 print('
    ')
    58 Province.class_func()
    59 Province.static_func()
    60 # 直接访问公有静态字段,公有静态字段通过类访问,在内存中只保存一份
    61 print(Province.name)
    62 
    63 obj.car #属性调用,自动执行 @property 修饰的car方法,并获取方法的返回值
    64 obj.car = 1000000 #自动执行 @property 修饰的car方法并赋值给参数
    65 del obj.car
    View Code

    ps:如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。

    类的特殊成员方法:

    __doc__  表示类的描述信息

    __module__ 表示当前操作的对象在那个模块

    __class__     表示当前操作的对象的类是什么

    __init__ 构造方法,通过类创建对象时,自动触发执行。

     __del__ 析构方法,当对象在内存中被释放时,自动触发执行。析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    __call__ 对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    __dict__ 查看类或对象中的所有成员   

    __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

    __getitem__、__setitem__、__delitem__  用于索引操作,如字典。分别表示获取、设置、删除数据

    __getslice__、__setslice__、__delslice__  该三个方法用于分片操作

    __iter__ 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__

     __metaclass__ 用来表示该类由 谁 来实例化创建

    PS:类的生成调用顺序依次是 __new__ --> __init__ --> __call__

    反射

    python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,该四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

     1 # -*- coding:utf-8 -*-
     2 __author__ = 'BillyLV'
     3 
     4 class test(super):
     5     def __init__(self):
     6         self.name = 'bill'
     7     def func(self):
     8         print('just testing')
     9 
    10 obj = test()
    11 
    12 # 检查是否含有成员
    13 print(hasattr(obj,'na'))#如无打印False
    14 print(hasattr(obj,'name'))#如有打印True
    15 print(hasattr(obj,'func'))
    16 
    17 # 获取成员
    18 getattr(obj,'name')#如没有会报错
    19 getattr(obj,'func')
    20 print(obj.name)
    21 print(getattr(obj,'name'))
    22 obj.func()
    23 print('-1-')
    24 
    25 # 设置成员
    26 setattr(obj,'name','lv')#把name值改为lv
    27 setattr(obj,'age','20')#添加age值为20
    28 setattr(obj, 'show', lambda num: num + 1)
    29 print(obj.age)
    30 print(getattr(obj,'age'))
    31 print(obj.show(2))
    32 print('----------',obj.name)
    33 print('-2-')
    34 
    35 # 删除成员
    36 delattr(obj,'age')
    37 #delattr(obj,'show')
    38 print(obj.show(4))
    39 obj.func()
    40 print(obj.name)
    41 print(getattr(obj,'name'))
    42 a=obj.__dict__['name']
    43 print(a)
    View Code

    异常处理

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


    python中的异常种类非常多,每个异常专门用于处理某一项异常。

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

     1 # -*- coding:utf-8 -*-
     2 __author__ = 'BillyLV'
     3 
     4 list1 = ['a','b']
     5 try:
     6     # 主代码块
     7     c = list1[1]
     8     f = open('file1')
     9 
    10 # 异常时,执行该块
    11 except IndexError as e:
    12     print('列表错误',e)
    13 except FileNotFoundError as e:
    14     print('文件异常',e)
    15 except Exception as e:
    16     print('未知错误',e)
    17 except BaseException as e:
    18     print('所有错误',e)
    19 
    20 # 主代码块执行完,执行该块
    21 else:
    22     print('一切正常')
    23 
    24 # 无论异常与否,最终执行该块
    25 finally:
    26     print('不管有没有错都执行')
    27 
    28 #主动触发异常
    29 try:
    30     raise Exception('出错了')
    31 except Exception as e:
    32     print(e)
    33 
    34 #手动触发异常,用于调试检查
    35 assert 1 == 1
    36 assert 1 == 2 # assert 条件
    View Code

    参考: 

    http://www.cnblogs.com/alex3714

    http://www.cnblogs.com/wupeiqi

    internet&python books

    PS:如侵权,联我删。

  • 相关阅读:
    项目中的*签到*小功能!
    亲们,拿到DateTime.Now你是否也是这样比较的?
    <input type="file" />,美化自定义上传按钮
    让你的页面实现自定义的 Ajax Loading加载的体验!
    按回车键提交表单!
    字符串比较大小,CompareTo来搞定!
    巧用Contains可以做到过滤同类项!
    项目开发中遇到的Bug知识整理!
    SharePoint中详细的版本对比
    ASP.NET安全隐患及SharePoint中的Workaround
  • 原文地址:https://www.cnblogs.com/BillyLV/p/10917726.html
Copyright © 2011-2022 走看看