• Python 面向对象(下)


    本篇博客承接自Python 面向对象(上)

    四. 继承,实现,依赖,关联,聚合,组合

    Python面向对象--继承,实现,依赖,关联,聚合,组合

    五. 特殊成员

    Python面向对象--类的特殊成员

     

    六. issubclass,type,isinstence各自的用法和区别

    1. issubclass

    语法: issubclass(class1, class2)
    参数: class1 和 class2 都是 类
    返回值: 返回 True 或 False -- 当class1是class2的家族成员时, 返回True, 否则返回False.

    举例说明:

    class Animal(object): pass
    class Cat(Animal): pass
    class BoSiCat(Cat): pass
    
    a = Animal()
    c = Cat()
    bsc = BoSiCat()
    
    # print(issubclass(c, Animal))
    # 报错: issubclass() arg 1 must be a class
    # print(issubclass(Cat, a))
    # 报错: issubclass() arg 2 must be a class or tuple of classes
    
    print(issubclass(BoSiCat, Cat))
    # 输出结果: True
    print(issubclass(BoSiCat, Animal))
    # 输出结果: True

    需要强调的是, issubclass()中的两个参数都是类!

    2. type

    语法: type(obj)
    参数: obj表示一个对象
    返回值: 返回创建这个对象的类(也即是对象obj的数据类型)

    举例说明:

    class Animal(object): pass
    class Cat(Animal): pass
    class BoSiCat(Cat): pass
    
    a = Animal()
    c = Cat()
    bsc = BoSiCat()
    
    print(type(a))      # 精准地判断出创建对象a的类是什么, 给出对象a的数据类型
    # <class '__main__.Animal'>
    print(type(c))
    # <class '__main__.Cat'>

    3. isinstence

    语法: isinstance(obj, classinfo)

    参数:
    obj -- 实例对象
    classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组

    返回值: 返回True或False -- 如果对象obj的类型与参数二classinfo的类型相同则返回 True,否则返回 False

    举例说明:

    class Animal(object): pass
    class Cat(Animal): pass
    class BoSiCat(Cat): pass
    
    a = Animal()    # 实例化
    c = Cat()
    bsc = BoSiCat()
    
    # print(isinstance(c, a))
    # 报错: isinstance() arg 2 must be a type or tuple of types
    
    print(isinstance(c, Animal))    # 判断对象c是否是类Animal
    # 输出结果: True
    print(isinstance(Cat, Animal))  # 判断类Cat是否是类Animal
    # 输出结果: False
    print(isinstance(Cat, type))    # 判断类Cat是否是类type
    # 输出结果: True

    根据上面的例子可以总结出:
    (1) isinstance()中的第一个参数必须是实例对象, 第二个参数必须是类名或由类名组成的元组.
    (2) 在上面的示例中, 注意到 print(isinstance(Cat, type)) 的执行结果是 True. 事实上, 如果把类也当作一个对象来看, 那么"类"这个对象是"type"类型的, 即"类"是"type"的家族成员.

    七. 面向对象中方法与函数的辨别

    在类外部: 都是函数

    在类内部:
    (1)属性 -- 无论谁访问, 属性既不是函数也不是方法
    (2)实例方法: 对象访问是方法, 类名访问是函数
    (3)静态方法: 无论谁访问, 静态方法都是函数
    (4)类方法: 无论谁访问, 类方法都是方法

    1. 在类的外部

    def func():
    print("我是函数func")
    
    print(func)
    # 执行结果: <function func at 0x00000188BC263E18>

    得出结论:

    在类外面定义的函数一定是函数

    2. 在类的内部

    class Foo:
    
        def instance_method(self):
            print("这里是实例方法")
            return "这里是实例方法的返回值"
    
        @staticmethod
        def static_method():
            pass
    
        @classmethod
        def class_method(cls):
            pass
    
        @property
        def age(self):
            return 10
    举例说明

    (1)属性

    class Foo:
        @property
        def age(self):
            return 10
    
    # 引入两个模块
    from types import FunctionType, MethodType
    
    # 定义一个函数,判断该参数是函数还是方法
    def function_method_judge(arg):
        print(isinstance(arg, FunctionType))
        print(isinstance(arg, MethodType))
    
    # 调用函数
    function_method_judge(Foo().age)
    print(Foo().age)
    
    # 执行结果: # False # False # 10

    得出结论:
    在@property的声明下, 我们定义的代码有着方法的表现形式(例如,他是有返回值的),但它既不是函数也不是方法.

    (2)实例方法

    a.对象去访问:

    # 定义一个实例方法
    class Foo:
        def instance_method(self):
            print("这里是实例方法")
            return "这里是实例方法的返回值"
    
    # 实例化
    f = Foo()
    
    # 对象访问实例方法名
    print(f.instance_method)

    以上代码的执行结果是:
    <bound method Foo.instance_method of <__main__.Foo object at 0x0000017D7D11AA90>>

    得出结论:
    对象访问实例方法 --> "实例方法"是"方法"

    b.类名去访问:

    # 定义一个实例方法
    class Foo:
        def instance_method(self):
            print("这里是实例方法")
            return "这里是实例方法的返回值"
    
    # 类名访问实例方法
    print(Foo.instance_method)

    以上代码的执行结果是:
    <function Foo.instance_method at 0x000002738C22B9D8>

    得出结论:
    类名访问实例方法 --> "实例方法"是"函数"

    (3)静态方法

    # 定义一个静态方法
    class Foo:
        @staticmethod
        def static_method():
            pass
    
    # 实例化
    f = Foo()
    
    # 对象访问静态方法
    print(f.static_method)
    # 类名访问静态方法
    print(Foo.static_method)

    以上代码的执行结果分别是:
    <function Foo.static_method at 0x0000018E170BB9D8>
    <function Foo.static_method at 0x0000018E170BB9D8>

    得出结论:
    无论是谁去访问静态方法, 静态方法都是函数

    (4)类方法

    class Foo:
        @classmethod
        def class_method(cls):
            pass
    
    # 实例化
    f = Foo()
    
    # 对象访问类方法
    print(f.class_method)
    # 类名访问类方法
    print(Foo.class_method)

    以上代码的执行结果分别是:
    <bound method Foo.class_method of <class '__main__.Foo'>>
    <bound method Foo.class_method of <class '__main__.Foo'>>

    得出结论:
    无论是谁去访问类方法, 类方法都是方法

    八. 反射

    反射: 利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动.

    1. hasattr

    描述: hasattr()函数用于判断对象是否包含对应的属性.

    语法: hasattr(object, name)

    参数:
    object -- 对象
    name -- 字符串类型的属性名字(强调: name是属性名)

    返回值: 如果对象有名字叫name的属性, 返回True, 否则返回False.

    举例说明:

    # 创建类
    class Person(object):
        def __init__(self, name, age, hobby):
            self.name = name
            self.age = age
            self.hobby = hobby
    
    # 实例化
    p = Person("王菲", 45, "唱歌")
    
    # 判断对象p是否有"name", "age", "hobby"属性
    print(hasattr(p, "name"))
    print(hasattr(p, "age"))
    print(hasattr(p, "hobby"))

    以上代码执行结果分别是:
    True
    True
    True

    得出结论: hasattr()函数用于判断对象是否包含"字符串类型的属性名"所对应的属性, 如果包含返回True, 否则返回False.

    2. getattr

    描述: getattr() 函数用于返回一个对象属性的值.

    语法: getattr(object, name)

    参数:
    object -- 对象
    name -- 字符串类型的属性名字

    返回值: 如果对象包含"该属性名对应的属性", 返回属性的值, 否则抛出一个异常: AttributeError.

    举例说明:

    # 创建类
    class Person(object):
        def __init__(self, name, age, hobby):
            self.name = name
            self.age = age
            self.hobby = hobby
    
    # 实例化
    p = Person("王菲", 45, "唱歌")
    
    # 从对象p中拿到对应的值
    value1 = getattr(p, "name")
    value2 = getattr(p, "age")
    value3 = getattr(p, "hobby")
    print(value1, value2, value3)
    
    # 尝试去拿一个p中没有的属性gender
    value4 = getattr(p, "gender")

    以上代码执行结果是:
    王菲 45 唱歌
    AttributeError: 'Person' object has no attribute 'gender'

    3. setattr

    描述: setattr()函数常常与getattr()配合使用, 用于设置属性值, 该属性必须存在.

    语法: setattr(object, name, value)

    参数:
    object -- 对象
    name -- 字符串类型的属性名字
    value -- 属性值

    返回值: 无

    举例说明:

    # 创建类
    class Person(object):
        def __init__(self, name, age, hobby):
            self.name = name
            self.age = age
            self.hobby = hobby
    
    # 实例化
    p = Person("王菲", 45, "唱歌")
    
    # 从对象p中拿到对应的值
    value1 = getattr(p, "name")
    value2 = getattr(p, "age")
    value3 = getattr(p, "hobby")
    print(value1, value2, value3)
    
    # 重新设置对象p的属性值
    setattr(p, "name", "刘德华")
    setattr(p, "age", 57)
    print(p.name, p.age, p.hobby)
    
    # 尝试给对象p设置一个他没有的属性
    setattr(p, "gender", "")
    print(p.gender)

    以上代码执行结果:
    王菲 45 唱歌
    刘德华 57 唱歌

    事实上, 在实际工作中, 当我们需要使用setattr()函数时, 我们必须征得相关领导或同事的同意才能进行操作, 否则, 当有人使用我们的代码时, 会给他们带来很大的困扰与不便. 因此, 对于setattr()函数我们要谨慎使用!

    4. delattr

    描述: delattr()函数用于删除对象的属性. 补充: delattr(obj, "name")相等于del obj.name

    语法: delattr(object, name)

    参数:
    object -- 对象
    name -- 字符串类型的属性名字, 对象必须包含该属性名对应的属性, 否则会抛出异常.

    返回值: 无

    举例说明:

    # 创建类
    class Person(object):
        def __init__(self, name, age, hobby):
            self.name = name
            self.age = age
            self.hobby = hobby
    
    # 实例化
    p = Person("王菲", 45, "唱歌")
    print(p.name, p.age, p.hobby)
    # 执行结果: 王菲 45 唱歌
    
    # 尝试删除一个对象的已有属性
    delattr(p, "hobby")
    # print(p.hobby)
    # 抛出一个异常:AttributeError: 'Person' object has no attribute 'hobby'
    
    # 尝试删除一个对象没有的属性
    # delattr(p, "gennder")
    # 抛出一个异常: AttributeError: gennder

    结论:
    当使用delattr()函数删除对象的属性后, 我们就无法再访问该属性了. 另外, 我们不能删除对象所没有的属性.

    九. 异常处理

    待补充

    参考资料: 错误处理

    十. MD5加密

    步骤说明:

    # 1. 引入模块hashlib
    import hashlib
    
    # 2. 创建一个MD5对象
    obj = hashlib.md5(b"complexity")   # 这里的complexity是可以更改的, 它的作用是让我们的密文更加难以被碰撞到
    
    # 3. 把要加密的内容转换成字节(byte)的形式交给MD5对象
    obj.update("encrypted_content".encode("utf-8"))
    
    # 4. 获取密文
    val = obj.hexdigest()
    print(val)
    # 打印结果是: acff9466e8cd1867e0a9d90755b55638 , 它就是"encrypted_content"的MD5密文

    实例应用:

    # 定义一个函数, 用于MD5加密
    def my_md5(val):
        obj = hashlib.md5(b"complexity")    # 创建一个MD5对象
        obj.update(val.encode("utf-8"))     # 把要加密的内容转换成字节的形式交给该MD5对象
        val = obj.hexdigest()               # 使用hexdigest()函数获取密文, 并将之赋给变量val
        return val                          # 返回密文

    十一. 日志处理

    Python之日志处理(logging模块)

    十二. super()的用法

    1. 回顾 -- 继承是什么?

    待补充

    2. MRO(method resolution order)

    (1)经典类MRO

    待补充

    (2)新式类MRO

    待补充

    3. super()的具体用法

    待补充

  • 相关阅读:
    分享图片到在线服务
    获取和保存照片
    处理图片(updated)
    简化版“询问用户是否退出”
    捕获高像素照片(updated)
    处理高像素的照片
    加强版照片捕获
    图片拍摄、处理、镜头应用
    Windows Phone 推送通知的第四类推送
    网络通信
  • 原文地址:https://www.cnblogs.com/haitaoli/p/9743614.html
Copyright © 2020-2023  润新知