python面向对象 : 反射和内置方法

一. 反射

1. isinstance()和issubclass()

  isunstance(类名, 对象名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属关系,只包括当前的类.)

  issubclass(类名, 类名) : 判断类与类之间的继承关系

class A:
    pass


class B(A):
    pass


b = B()
print(isinstance(b, B))  # True  判断对象b是否属于B类
print(isinstance(b, A))  # True  判断对象b是否属于A类
print(type(b) is B)  # True   判断对象b是否属于B类
print(type(b) is A)  # False  判断对象b是否属于A类

print(issubclass(A, B))  # False  判断A是不是B的子类
print(issubclass(B, A))  # True   判断B是不是A的子类

2. 反射

  反射 : 用字符串数据类型的变量名来访问这个变量的值. python中的一切事物都是对象(都可以使用反射)

  反射的方法 : getattr , hasattr,  setattr,  delattr

(1) getattr

  getattr 接收2个参数,前面的是一个对象或者模块,后面的是一个字符串.

  语法 : 命名空间.XXX == getattr(命名空间,'XXX')

#从类的角度看:

class A:
    name = 'jack'
    @classmethod
    def func(cls):
        print(666)
    @staticmethod
    def func1():
        print(777)

# 反射查看静态属性
print(A.name)  # jack
print(getattr(A, 'name'))  # jack
# 反射调用方法
A.func()  # 666
print(getattr(A, 'func'))  # <bound method A.func of <class '__main__.A'>> 内存地址
getattr(A, 'func')()  # 666   类方法

A.func1()  # 777
print(getattr(A, 'func1'))  # <function A.func1 at 0x000002436F709620>  内存地址
getattr(A, 'func1')()  # 777  静态方法
# 从对象的角度来看

class A:
    NAME = 'STEVE'  # 全局变量和类中的静态属性最好全大写

    @classmethod
    def func(cls):
        print(666)

    @staticmethod
    def func1():
        print(777)


a = A()
# 反射查看静态属性
print(getattr(a, 'NAME'))  # STEVE
# 反射调用方法
 # 类方法
getattr(a, 'func')()  # 666
 # 静态方法
getattr(a, 'func1')()  # 777
# 从模块的的角度

  # 导入系统模块
import os # 导入os模块 os模块是别人写好的python代码的结合 os.rename('12', 'hello') # 把文件为'123'的文件名改为'hello' getattr(os, 'rename')('hello', '12') # 把文件为'hello'的文件名改为'456' ==>> os.rename # 导入自己的模块 def func1(): print(666) def func2(): print(777) import sys # 是一个模块,这个模块里的所有的方法都是和python解释器相关的 print(sys.modules) # 这个方法 表示所有在当前这个python程序中导入的模块 # 可以找到本文件的模块地址(字典类型): '__main__' from 'D:/pycharm/练习/week05/new21.py'> print(sys.modules['__main__']) # <module '__main__' from 'D:/pycharm/练习/week05/new21.py'> file = sys.modules['__main__'] file.func1() # 666 file.func2() # 777 getattr(file, 'func1')() # 666 getattr(file, 'func2')() # 777

(2) hasattr

class A:
    name = 'tom'
    def __init__(self):
        self.age = 18
a = A()

print(hasattr(A, 'name'))  # True  判断A类是否含有name属性
print(hasattr(a, 'age'))   # True  判断对象a是否含有age属性
print(hasattr(a,'sex'))   # False

(3) setattr , delattr

class A:
    def __init__(self,name):
        self.name = name

a = A('tom')
setattr(a,'name', 'jack')  # 把对象a的属性name的值改成'jack'
print(a.name)  # jack
print(a.__dict__)  # {'name': 'jack'}


delattr(a,'name')  # 删除对象a的name属性
print(a.__dict__)  # {}

二. 内置方法

       格式 :   __名字__              称呼 : 类中的特殊方法\内置方法 双下方法 魔术方法 (magic_method)

  类中的每一个双下方法都有它自己的特殊意义 , 所有的双下方法没有需要你在外部直接调用的, 而是总有一些其他的内置函数特殊的语法来自动触发这些双下方法

1. __call__

  功能 : 对象后面加括号,触发执行。即:对象() 或者 类()()

class A:
    DAY = 'MONDAY'
    def __call__(self):
        print('666')

a = A()
a()  # 666   自动执行__call__方法
A()()  # 666

2. __len__

class A:
    def __init__(self):
        self.lst = [1, 2, 3, 4, 5, 6, 7]
    def __len__(self):
        print(666)
        return len(self.lst)

a = A()  # 实例化对象
print(len(a))  # 7  len()自动执行__len__方法

3. __str__

class A:
    def __str__(self):
        return '%s %s %s %s %s' %(self.name, self.age, self.sex, self.height, self.weight)
    def __init__(self, name, age, sex, height, weight):
        self.name = name
        self.age = age
        self.sex = sex
        self.height = height
        self.weight = weight

a = A('jack', 18, '', 55, 1.85)
print(a)  # print一个对象相当于调用一个对象的__str__方法
# jack 18 男 55 1.85
print(str(a))  # 内置的数据类型,内置的类,相当于执行__str__
# jack 18 男 55 1.85
print('1号: %s' %a)  # 1号: jack 18 男 55 1.85

4. __new__

  __new__ : 构造方法

  在实例化之后,__init__之前先执行new来创建一块空间

class A:
    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls)  # A类没有__new__,只能去找object里找
        print('第一步')
        return obj
    def __init__(self):
        print('第二步')
a = A()  # 先执行__new__方法,再执行__init__方法
# 第一步
# 第二步

  单例类

# 单粒类 : 只能实现一个实例化对象空间的类
class A:
    __INSTANCE = None
    def __new__(cls):
        if not cls.__INSTANCE :
            cls.__INSTANCE = object.__new__(cls)
            return cls.__INSTANCE
    def __init__(self):pass

a1 = A()
a2 = A()
a3 = A()
print(a1)  # <__main__.A object at 0x000002096E378B38>
print(a2)  # None
print(a3)  # None

猜你喜欢

转载自www.cnblogs.com/huangqihui/p/9393030.html