zoukankan      html  css  js  c++  java
  • Python基础---面向对象3

    1.函数与方法的判断

      1.1 通过打印类名的方式

    class A:
        def func(self):
            pass
    def func():
        pass
    print(A.func)     <function A.func at 0x000001ED27190BF8>
    print(func)       <function func at 0x0000028B166C2EA0>
    obj = A()
    print(obj.func)   <bound method A.func of <__main__.A object at 0x0000028B1689E9E8>>

      1.2 借助FunctionType,MethodType

    from types import FunctionType
    from types import MethodType
    def func():
        pass
    class A:
        def func(self):
            pass
    obj = A()
    print(isinstance(func,FunctionType))        # True,函数
    print(isinstance(A.func,FunctionType))     # True,函数
    print(isinstance(obj.func,MethodType))     # True,方法

      1.3 类中的实例方法:

          如果通过类名调用,就是FunctionType

          如果通过实力调用,就是MethodType

        类中的类方法:

          类中的类方法: 是方法MethodType

          类中的静态方法: 是函数FunctionType

      1.4 方法和函数的区别

         函数显性传参,不依赖于对象

        方法是隐性传参,要依赖对象,类

    2.类的约束

      制定了一个强制的标准,强制子类要有父类规定的方法(并没有做到强制的规范,如果不继承,约束就没用)

      2.1 raise Exception(),主动报错,在父类的方法中主动抛出异常

    class Payment:
         def pay(self,money):
             raise Exception('子类要定义pay方法!!!')
     class Alipay(Payment):
         def pay(self,money):
             print('使用阿里支付了%s元'% money)
     class QQpay(payment):
         def pay(self,money):
             print('使用QQ支付了%s元'% money)
    class WeChatpay(self,money):
        def zhifu(self,money):
            print('使用微信支付了%s钱'% money)
    def pay(self,money):            *****   统一了支付方式,归一化设计
        obj.pay(money)
    obj1 = Alipay()
    obj2 = WeChatpay()
    obj1.pay(10)
    obj2.pay(10)

      2.2 引用抽象类,接口类;子类实例化对象时没有这个方法就报错

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):    # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
        @abstractmethod
        def pay(self):
            pass  # 抽象方法
    
    class Alipay(Payment):
        def pay(self,money):
            print('使用支付宝支付了%s元'%money)
    class WeChat(Payment):
        def zhifu(self,money):
            print('使用微信支付了%s元'%money)
    def pay(a,money):
        a.pay(money)
    
    ali
    = Alipay() ali.pay(100) pay(ali,money)    # 归一化设计,不管是哪一个类的对象,都调用同一个函数完成相似功能
    we
    = Wechat() we.zhifu()      # 用的时候就会报错
    pay(we,
    100)

    3.类的成员

      3.1类方法(使用装饰器@classmethod)

        主动接收类名,与类的静态属性相关,与对象无关的需求,需要使用类方法

        类名.类方法  对象.类方法, 传给cls的都是类空间

    设置一个场景: 计算班级学生人数
    class
    Student: stu_num = 0 def __init__(self,name,age): self.name = name self.age = age Student.add_num() @classmethod def add_num(cls): cls.stu_num += 1 def get_num(self): return cls.stu_num ali = Student('阿狸',6) tuan = Student('团子',5) print(Student.get_num()) 结果为2

      3.2静态方法(使用装饰器@staticmethod)

        静态方法不依赖于对象和类,但是为了保持代码的一致性和整体性,可以将其设置为静态方法,是一个独立的,单纯的函数

    设定一个场景,时间操作,其中有一个获取当前时间的函数
    import time
    class Timetest:
        def __init__(self,hour,minute,second):
            self.hour = hour
            self.minute = minute
            self.second = second
        @staticmethod
        def showTime():
            return time.strftime('%H:%M:%S',time.localtime())
    print(Timetest.showTime)
    t = Timetest(2,10,10)
    now_time = t.showTime()
    print(now_time)

      3.3属性(使用装饰器@property)

        用的最多,也见的最多

    写法一:

    class A:
        def __init__(self)
            pass
        @property
        def AAA(self):
            print('执行的时候执行')
        @AAA.setter
        def AAA(self):
            print('修改的时候执行')
        @AAA.deleter
        def AAA(self):
            print('删除的时候执行')
    f1 = A()
    f1.AAA
    f1.AAA = 'aaa'
    del f1.AAA

    写法二:

    class Foo:
        def get_aa(self):
            print('')
        def set_aa(self):
            print('')
        def del_aa(self):
            print('')
        aa = property(get_aa,set_aa,del_aa)
    f1 = Foo()
    f1.aa
    f1.aa = 'aaa'
    del f1.aa

      3.4特殊的双下方法

      双下方法是解释器提供的由 __方法名__的具有特殊意义的方法,主要是python源码程序员使用,深入的研究双下方法,会更便于阅读源码.不同的双下方法有不同的触发方式

      __init__,实例化对象时,就执行__init__方法

      __len__

    class A:
        def __len__(self):
            print(666)
    a = A()
    len(a)           # 只要len一个实例化对象,就会出发__len__方法
    
    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))

      __hash__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    a = A()
    print(hash(a))            # 随机生成一个哈希值,hash一个实例化对象就调用

      __str__

    class A:
        def __str__(self):
            return '123'      return后面不能是 int 类型
    a = A()
    print(a)
    print('%s'%a)          # 打印对象时,默认输出该方法的返回值

      __repr__

    class A:
        def __repr__(self):
            return '太白'
    a = A()
    print(repr(a))
    print('%r'%a)          # repr(对象)时,默认输出该方法的返回值

      __call__

    class A:
        def __call__(self,*args,**kwargs):
            print('__call__')
    a = A()
    a()
    A()()              # 对象+()触发执行__call__方法,或是类名()()

      __eq__

    def __init__(self):
        self.a = 1
        self.b = 2
    def __eq__(self,obj):
        if self.a == obj.a and self.b == obj.b
            return True
    a = A()
    b = B()
    print(a==b)          # 比较两个实例化对象时触发

      __new__构造方法

    class A:
        def __init__(self):
            self.x = 1
            print('in init')
        def __new__(cls,*args,**kwargs):
            print('in new')
            return object.__new__(A,*args,**kwargs)
    a = A()
    print(a.x)

      单例模式:一种常用的软件设计模式,通过单例模式可以保证系统中一个类只有一个实例,且该实例易于被外界访问,从而可以节约系统资源,控制实例个数

    class A:
        def __new__(cls,*args,**kwargs):
            if cls.a is None:
                obj = object.__new__(cls)
                cls.a = obj
            return cls.a

      __item__

    class A:
        def __init__(self,name):
            self.name = name
        def __getitem__(self,item):
            print('self.__dict__[item]')
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
    a = A()
    a['age'] = 18                 # 自动触发__setitem__
    del a['age']                 # 触发__delitem__
    a['name'] = 'alex'              # 自动触发__setitem__
    print(a.__dict__)

      __enter__和__exit__: 上下文管理

    class A:
        def __init__(self, text):
            self.text = text
        def __enter__(self):  # 开启上下文管理器对象时触发此方法
            self.text = self.text + '您来啦'
            return self  # 将实例化的对象返回f1
        def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
            self.text = self.text + '这就走啦'
        
    with A('大爷') as f1:
        print(f1.text)
    print(f1.text)

    4.反射: 通过字符串对实例化对象进行相应操作

      hasattr,检测是否含有某种属性,  getattr,获取某个属性

      setattr,设置某个属性,      delattr,删除某个属性

      01. 对对象进行反射

    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    obj = A('小胖',18)
    print(hasattr(obj, 'name'))
    print(getattr(obj, 'age'))
    setattr(obj,'sex','')
    print(obj.__dict__)        # {'name':'小胖','age':18,'sex':'男'}
    delattr(obj,'age')
    print(obj.__dict__)        # {'name':'小胖','sex':'男'}

      02. 对类的反射

    class A:
        country = '中国'
        def __init__(self):
            self.name = '小胖'
        def func(self):
            return 'func'
        @staticmethod
        def bar():
            return 'bar'
    print(getattr(A,'country'))      # 中国
    print(getattr(A,'func'))   方法名内存# <function A.func at 0x000002BE2ABA0C80>
    print(getattr(A,'bar'))    # <function A.bar at 0X000002BE2ABD8048>

      03. 当前模块的反射

    import sys
    def foo():
        print('in foo')
    def func():
        print('in func')
    
    module = sys.modules[__name__]
    print(hasattr(module,'foo'))        # True
    getattr(module,'func')            # in func

      04. 其他模块的反射

    import 另一个模块名
    print(hasattr(模块名, 方法名或属性名))
    foo = getattr(模块名, 属性名)
    print(foo)                              属性值
    ret = getattr(模块名,方法名)
    ret()                     # 调用另一个模块的方法

    5.isinstance和issubclass

      isinstance: 判断对象是否为类的实例化对象

    class A:
        pass
    class B(A):
        pass
    obj = B()
    print(isinstance(obj,B))

      issubclass: 判断此类是否为另一个类的派生类

    class A:
        pass
    class B(A):
        pass
    class C(B):
        pass
    print(issubclass(B,A))
    print(issubclass(C,A))
  • 相关阅读:
    C#根据url生成唯一的key
    MyBatis基本配置和实践(四)
    MyBatis基本配置和实践(三)
    MyBatis基本配置和实践(二)
    MyBatis基本配置和实践(一)
    dbcp2、c3p0、druid连接池的简单配置
    HTTP长连接和短连接
    Java Web高性能开发
    三层构架 和 MVC 是什么?
    Docker bridge探索
  • 原文地址:https://www.cnblogs.com/py8318/p/10353601.html
Copyright © 2011-2022 走看看