面向对象中特殊方法的补充isinstance/issubclass/type方法和函数反射

Posted qq849784670

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象中特殊方法的补充isinstance/issubclass/type方法和函数反射相关的知识,希望对你有一定的参考价值。

一、面向对象中特殊方法的补充

  1.__str__  能将对象名改成你想要的字符串,但是类型还是类

class Foo(object):

    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "f1"

obj = Foo()
print(obj,type(obj))
# f1 <class ‘__main__.Foo‘>  

  2.__doc__  能将类的注释文档显示出来

class Foo(object):
    ‘‘‘
    asdqwe
    ‘‘‘
    def __init__(self):
        pass

    def func(self):
        pass
obj = Foo()
print(obj.__doc__)
# asdqwe

  3.__dict__  能将对象中封装的数据以字典的形式输出

class Foo(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def func(self):
        pass

obj1 = Foo("a1",14)
obj2 = Foo("a2",15)
print(obj1.__dict__)    #{‘name‘: ‘a1‘, ‘age‘: 14}
print(obj2.__dict__)    #{‘name‘: ‘a2‘, ‘age‘: 15}

  4.__iter__  

    如果想要把不可迭代对象转变成可迭代对象:

      1.在类中定义__iter__方法

      2.iter内部返回一个迭代器(生成器也是一种特殊迭代器)

class Foo(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass
    def __iter__(self):
        return iter([11,22,33,44])
obj =   Foo("a1",13)
for el in obj:
    print(el)
# 11
# 22
# 33
# 44

几个实例:

class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11,22]


s1 = StarkConfig()

result1 = s1.get_list_display()
print(result1) # [33]

result2 = s1.get_list_display()
print(result2) # [33,33]
class StarkConfig(object):
    def __init__(self):
        self.list_display = []

    def get_list_display(self):
        self.list_display.insert(0, 33)
        return self.list_display


class RoleConfig(StarkConfig):
    list_display = [11, 22]


s1 = StarkConfig()

result1 = s1.get_list_display()
print(result1)  # [33]

result2 = s1.get_list_display()
print(result2)  # [33, 33]

二、sinstance/issubclass/type三种方法

  1.issubclass  #检查第一个参数是否是第二个参数的子类或子孙类

class Base(object):
    pass
class Foo(Base):
    pass
class Bar(Foo):
    pass
print(issubclass(Bar,Base))
print(issubclass(Foo,Base))
# True
# True

  2.type  #获取当前对象是由哪个类创建的

class Foo(object):
    pass

obj = Foo()

print(obj, type(obj))  # 获取当前对象是由那个类创建。
if type(obj) == Foo:
    print(obj是Foo类型)
# obj是Foo类型

    练习题

技术分享图片
class Foo(object):
    pass

class Bar(object):
    pass

def func(*args):
    foo_counter = 0
    bar_counter = 0
    for item in args:
        if type(item) == Foo:
            foo_counter += 1
        elif type(item) == Bar:
            bar_counter += 1
    return foo_counter, bar_counter    #函数返回值为多个值以元组的形式返回


result = func(Foo(),Bar(),Foo())
print(result)

v1, v2 = func(Foo(), Bar(), Foo())    #解构
print(v1, v2)
View Code

  3.isinstance  判断第一个参数(对象),是否是第二个参数(类及父类)的实例

class Bar(object):
    pass
class Base(Bar):
    pass
class Foo(Base):
    pass
obj1 = Foo()
print(isinstance(obj1,Foo))
print(isinstance(obj1,Base))
print(isinstance(obj1,Bar))
# True
# True
# True

    **type:判断对象是不是由某一个指定类 type(obj)==Foo

    **isinstance:判断对象是不是由某一个指定类或其父类 isinstance(obj,Foo)

三、判断是方法还是函数

  称谓:类,方法

       外,函数

      对象.xxx---->xxx就是方法

      类.xxx   ----->xxx就是函数

      xxx  ------>xxx就是函数

    代码判断:

技术分享图片
from types import FunctionType,MethodType
def check(arg):
    """
    检查arg是函数还是方法
    :param arg:
    :return:
    """
    if isinstance(arg,FunctionType):
        print("arg是一个函数")
    elif isinstance(arg,MethodType):
        print("arg是一个方法")
    else:
        print("arg什么都不是")
class Foo():
    def f1(self):
        pass
obj = Foo()
check(obj.f1)   #arg是一个方法
check(Foo.f1)   #arg是一个函数
View Code

四、反射

  getattr  根据字符串的形式,去对象中找成员  v = getattr(obj,"func") 

  hasattr  根据字符串的形式,去判断对象中是否有成员

  setattr  根据字符串的形式,动态的设置一个成员(内存)

  delattr  根据字符串的形式,动态的删除一个成员(内存)

技术分享图片
from types import FunctionType
import handler

while True:
    print("""
    系统支持的函数有:
        1. f1
        2. f2
        3. f3
        4. f4
        5. f5
    """)
    val = input("请输入要执行的函数:")  # val = "f1"

    # 错误
    # handler.val()
    if hasattr(handler, val):
        func_or_val = getattr(handler, val)  # 根据字符串为参数,去模块中寻找与之同名的成员。
        if isinstance(func_or_val, FunctionType):
            func_or_val()
        else:
            print(func_or_val)
    else:
        print(handler中不存在输入的属性名)
View Code
技术分享图片
class Account(object):
    func_list = [login, logout, register]

    def login(self):
        """
        登录
        :return:
        """
        print(登录111)

    def logout(self):
        """
        注销
        :return:
        """
        print(注销111)

    def register(self):
        """
        注册
        :return:
        """
        print(注册111)

    def run(self):
        """
        主代码
        :return:
        """
        print("""
            请输入要执行的功能:
                1. 登录
                2. 注销
                3. 注册
        """)

        choice = int(input(请输入要执行的序号:))
        func_name = Account.func_list[choice - 1]

        # func = getattr(Account,func_name) # Account.login
        # func(self)

        func = getattr(self, func_name)  # self.login
        func()


obj1 = Account()
obj1.run()

obj2 = Account()
obj2.run()
View Code
callable  判断是否能被调用



以上是关于面向对象中特殊方法的补充isinstance/issubclass/type方法和函数反射的主要内容,如果未能解决你的问题,请参考以下文章

面向对象之组合的补充,主动调用其他类的成员,特殊成员

Python 面向对象(下)

Python开发第七篇: 面向对象和模块补充

python面向对象魔术方法补充

面向对象补充之方法

面向对象遗忘补充