zoukankan      html  css  js  c++  java
  • 面向对象之反射和内置方法

    静态方法

    静态方法(staticmethod)和类方法(classmethod)

    类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性)

    静态方法:让类里的方法直接被类调用,就像正常调用函数一样

    类方法和静态方法的相同点:都可以直接被类调用,不需要实例化

    类方法和静态方法的不同点:

      类方法必须有一个cls参数表示这个类,可以使用类属性

      静态方法不需要参数

    绑定方法:分为普通方法和类方法

         普通方法:默认有一个self对象传进来,并且只能被对象调用-------绑定到对象

          类方法:默认有一个cls对象传进来,并且可以被类和对象(不推荐)调用-----绑定到类

    非绑定方法:静态方法:没有设置默认参数,并且可以被类和对象(不推荐)调用-----非绑定

    1 class Student:
     2     f = open('student', encoding='utf-8')
     3     def __init__(self):
     4         pass
     5     @classmethod #类方法 :有个默认参数cls,并且可以直接使用类名去
     6                  #调用,还可以与类属性交互(也就是可以使用类属性)
     7     def show_student_info_class(cls):
     8         # f = open('student', encoding='utf-8')
     9         for line in cls.f:
    10             name,sex = line.strip().split(',')
    11             print(name,sex)
    12     @staticmethod  #静态方法:可以直接使用类名去调用,就像正常的函数调用一样
    13     def show_student_info_static(): #不用传self
    14         f = open('student',encoding='utf-8')
    15         for line in f:
    16             name,sex = line.strip().split(',')
    17             print(name,sex)
    18 # egon = Student()
    19 # egon.show_student_info_static()  #也可以这样调,但是还是推荐用类名去调
    20 # egon.show_student_info_class()
    21 
    22 Student.show_student_info_class()#类名.方法名()
    23 print('-------------------')
    24 Student.show_student_info_static()#类名.方法名()
    staticmethod和classmethod

    isinstance 和 issubclass

    isinstance(obj,cls):检查obj是不是cls的对象(传两个参数,一个是对象,一个是类)

    issubclass(sub,super):检查sub是不是super的子类(传两个参数,一个是子类,一个是父类)

     1 class Foo:
     2     pass
     3 class Son(Foo):
     4     pass
     5 s = Son()
     6 print(isinstance(s,Son))  #判断s是不是Son的对象
     7 print(type(s) is Son)
     8 print(isinstance(s,Foo))  #判断s是不是Foo的对象  不精准
     9 print(type(s) is Foo)  #type比较精准
    10 
    11 print(issubclass(Son,Foo)) #判断Son是不是Foo的子类
    12 print(issubclass(Son,object))
    13 print(issubclass(Foo,object))
    14 print(issubclass(int,object))
    View Code

    反射

    反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用反射。

    反射有四种方法:

    hasattr:hasattr(object,name)判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

    getattr:获取对象的属性或者方法,如果存在则打印出来。hasattr和getattr配套使用

        需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

    setattr:给对象的属性赋值,若属性不存在,先创建后赋值

    delattr:删除该对象指定的一个属性

    1 class Foo:
     2     def __init__(self):
     3         self.name = 'egon'
     4         self.age = 51
     5     def func(self):
     6         print('hello')
     7 egg = Foo()
     8 setattr(egg,'sex','')
     9 print(egg.sex)
    10 # 2.
    11 def show_name(self):
    12     print(self.name+'sb')
    13 setattr(egg,'sh_name',show_name)
    14 egg.sh_name(egg)
    15 show_name(egg)
    setattr
    1 delattr(egg,'name')
    2 print(egg.name)
    delattr

    1.对象应用反射

    1 class Foo:
     2     def __init__(self):
     3         self.name = 'egon'
     4         self.age = 51
     5     def func(self):
     6         print('hello')
     7 egg = Foo()
     8 print(hasattr(egg,'name'))  #先判断name在egg里面存在不存在
     9 print(getattr(egg,'name')) #如果为True它才去得到
    10 print(hasattr(egg,'func'))
    11 print(getattr(egg,'func'))  #得到的是地址
    12 # getattr(egg,'func')()  #在这里加括号才能得到,因为func是方法
    13 if hasattr(egg,'func'):
    14     getattr(egg,'func')()
    15 else:
    16     print('没找到')
    View Code

    2.类应用反射

    1 class Foo:
     2     f = 123
     3     @classmethod
     4     def class_method_dome(cls):
     5         print('class_method_dome')
     6 
     7     @staticmethod
     8     def static_method_dome():
     9         print('static_method_dome')
    10 print(hasattr(Foo,'class_method_dome'))
    11 method = getattr(Foo,'class_method_dome')
    12 method()
    13 print('------------')
    14 print(hasattr(Foo,'static_method_dome'))
    15 method1 = getattr(Foo,'static_method_dome')
    16 method1()
    View Code

    3.模块应用反射

    模块的应用又分为导入其他模块反射和在本模块中反射

    1 # 1.导入其他模块引用
    2 import mymodule
    3 print(hasattr(mymodule,'test'))
    4 getattr(mymodule,'test')()
    5 
    6 # # 这里的getattr(mymodule,'test')()这一句相当于
    7 # p = getattr(mymodule,'test')
    8 # p()
    导入其他模块反射
    1 # 2.在本模块中应用反射
    2 def demo1():
    3     print('wwww')
    4 import sys
    5 # print(sys.modules)
    6 module_obj = sys.modules[__name__]  #相当于'__main__'
    7 print(module_obj)
    8 print(hasattr(module_obj,'demo1'))
    9 getattr(module_obj,'demo1')()
    在本模块中应用反射
     1 # 举例
     2 def 注册():
     3     print('regiester')
     4 def 登录():
     5     print('login')
     6 def 购物():
     7     pass
     8 print('注册,登录,购物')
     9 ret = input('请输入你要做的操作:')
    10 import sys
    11 my_module = sys.modules[__name__]  #利用sys模块导入一个自己的模块
    12 if hasattr(my_module,ret):
    13     getattr(my_module,ret)()
    导入自己模块的示例

    反射补充:

    db.mysql

    class MySQlHelper(object):
        print('MySQlHelper1111111')
        def fetchone(self):
            print('你好')

    db.pool

    class PoolHelper(object):
        print('PoolHelper')

    settings.py

    DB_PATH = 'db.mysql.MySQlHelper'
    
    #吧字符串切割
    module_name,cls_name = DB_PATH.rsplit('.',maxsplit=1)
    # print(module_name,cls_name)  #db.mysql    MySQlHelper
    #导入模块
    # from db.mysql import MySQlHelper
    import importlib
    moudel_obj = importlib.import_module(module_name)
    print(moudel_obj,type(moudel_obj))
    #导入模块中的类
    cls = getattr(moudel_obj,cls_name)
    print(cls)
    #对类进行实例化
    obj = cls()
    obj.fetchone()
    # getattr()

    内置方法

    1.__str__和__repr__

    改变对象的字符串显示

     1 class Foo:
     2     def __init__(self,name):
     3         self.name = name
     4     def __repr__(self):
     5         return 'obj in str'  #这里只能是return
     6     # def __str__(self):
     7     #     return '%s obj in str'%self.name
     8 f = Foo('egon')
     9 print(f)  #优先执行__str__里面的内容
    10 # 那么你是不是据地__repr__没用呢?
    11 # print('%s'%f)  #执行的是__str__里面的返回值
    12 # print('%r'%f)  #执行的是__repr__里面的返回值
    13 print('==============')
    14 print(str(f))  #当执行str(f)时,会去找__str__这个方法,如果找不到的时候,__repr__这个方法就给替补了
    15 print(repr(f))
    16 #1.当打印一个对象的时候,如果实现了__str__方法,打印__str__中的返回值
    17 # 2.当__str__没有被实现的时候,就会调用__repr__方法
    18 # 3.但是当你用字符串格式化的时候,%s和%r会分别调用__str__和__repr__方法
    19 # 4.不管是在字符串格式化的时候还是在打印对象的时候,
    20 # __repr__方法都可以作为__str__方法的替补,但反之则不行
    21 # 5.用于友好的表示对象。如果__str__和__repr__方法你只能实现一个:先实现__repr__
    View Code

     2.__del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    1 class Foo:
    2     def __del__(self):
    3         print('执行我啦')
    4 
    5 f= Foo()
    6 print(123)
    7 print(123)
    8 print(123)
    9 print(123)

    3.item系列

    分别有__getitem__      ,__setitem__    ,__delitem__

     1 class Foo:
     2     def __init__(self):
     3         self.name = 'egon'
     4         self.age = 73
     5         self.l=[1,2,3]
     6     def __getitem__(self, item):  #得到
     7         # return  self.l[item]
     8         # return self.__dict__[item]
     9         # print(Foo.__dict__)
    10         return 123
    11     def __setitem__(self, key, value):  #修改
    12         print(key,value)
    13         self.__dict__[key] = value
    14     def __delitem__(self, key):  #删除
    15         del self.__dict__[key]
    16 f = Foo()
    17 print(f['qqq'])  #不管里面放的啥值,它都会得到返回值的内容,调用的是__getitem__方法
    18 f['name']='alex' #修改egon的值为alex,调用 __setitem__方法
    19 # del f['name'] #删除name,就会报错了,说明在调用__delitem__方法调用成功了,就已经删了,就会报错了
    20 print(f.name) 
    21 f1 = Foo()
    22 print(f == f1)
    23 # print(f.name)
    24 # print(f[0])  #一开始不能这样取值,但是提供了一个__getitem__方法,这样就可以用了
    25 # print(f[1])
    26 # print(f[2])
    三种方法使用示例

    4.__new__(创建)

    1 # 4.__new__方法
     2 # 单例模式:是一种设计模式
     3 class Singleton:
     4     def __new__(cls, *args, **kw):
     5         if not hasattr(cls, '_instance'):
     6             orig = super(Singleton, cls)
     7             cls._instance = orig.__new__(cls, *args, **kw)
     8         return cls._instance
     9 
    10 one = Singleton()
    11 two = Singleton()
    12 print(one,two)   #他们两个的地址一样
    13 
    14 one.name = 'alex'
    15 print(two.name) 
    单例模式
    1 # class A:
     2 #     def __init__(self):  #有一个方法在帮你创造self
     3 #         print('in init function')
     4 #         self.x = 1
     5 #
     6 #     def __new__(cls, *args, **kwargs):
     7 #         print('in new function')
     8 #         return object.__new__(A, *args, **kwargs)
     9 # a = A()
    10 # b = A()
    11 # c = A()
    12 # d = A()
    13 # print(a,b,c,d)
    __new__

    5.__call__

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

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

    1 class Foo:
    2     def __call__(self, *args, **kwargs):
    3         print(123)
    4 # f = Foo()
    5 # f() #如果不写上面的__call__方法,就不会调用。如果加上,就正确了
    6 Foo()() #也可以这样表示

    6.__len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))

    7.__hash__

    1 class Foo:
    2     def __hash__(self):
    3         print('aaaaaaaaaa')
    4         return hash(self.name)
    5         # print('aaas')
    6 f = Foo()
    7 f.name = 'egon'
    8 print(hash(f))  #hash方法是可以重写的

    8.__eq__

    1 class A:
    2     def __eq__(self, other):
    3         return True
    4 a = A()
    5 b = A()
    6 print(a==b) #不加方法的时候返回的是False,加了个__eq__方法就返回了个True
    7 # '=='内部就调用了__eq__方法
    8 print(a is b)

    小游戏和面试题

    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))
    纸牌游戏
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __hash__(self):
            return hash(self.name+self.sex)
    
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:return True
    
    
    p_lst = []
    for i in range(84):
        p_lst.append(Person('egon',i,'male'))
    
    print(p_lst)
    print(set(p_lst))
    面试题
  • 相关阅读:
    springmvc
    POJ 3683 Priest John's Busiest Day
    POJ 3678 Katu Puzzle
    HDU 1815 Building roads
    CDOJ UESTC 1220 The Battle of Guandu
    HDU 3715 Go Deeper
    HDU 3622 Bomb Game
    POJ 3207 Ikki's Story IV
    POJ 3648 Wedding
    HDU 1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/bypp/p/8657333.html
Copyright © 2011-2022 走看看