016 方法和函数的区分、子类的判断和反射

1. 子类的判断:

class Base:
    pass
class Father(Base):
    pass
class Son(Father):
    pass

# issubclass  判断第一个参数(类),是否为第二个参数的子类(子子孙孙类)
print(issubclass(Son, Father))  # True
print(issubclass(Son, Base))  # True

# type 检查该对象由哪个类创建
obj = Father()
print(type(obj))  # <class '__main__.Father'>
print(type(obj) == Father)    # True
print(type(obj) == Base)      # False

# isinstance() 判断第一个参数(对象),是否为第二个参数(类及父类)的实例
print(isinstance(obj, Base))    # True
print(isinstance(obj, Father))  # True
print(isinstance(obj, Son))     # False

2. 方法和函数的区分:

from types import MethodType, FunctionType

class Foo():
    country = 'China'
    def __init__(self, name):
        self.name = name
    def f1(self):
        print(self.name)
    def f2(self):
        print('hello2')

    @staticmethod
    def f3():
        print(f1)

    @classmethod
    def f4(cls):
        print('%s f2' % cls.country)

obj = Foo('小明')  # 实例化
# 通过print查看, 输出中带有 method 的为方法,带有 function 的为函数
print(obj.f1)    # 方法
print(obj.f2)    # 方法
print(Foo.f3)    # 函数
print(Foo.f4)    # 方法

# 通过 types 模块的 MethodType 和 FunctionType 判断
def check(arg):
    if isinstance(arg, MethodType):
        print('这是方法')
    elif isinstance(arg, FunctionType):
        print('这是函数')
    else:
        print('即不是方法,也不是函数')

check(obj.f1)
check(obj.f2)
check(Foo.f3)
check(Foo.f4)

这是严格判断方法和函数的示例,但我们一般把类中的函数都称为方法。

3. 反射:

根据字符串参数,寻找对象中对应的方法,并进行相应操作。

class Foo():
    def f1(self):
        print('1111')
    def f2(self):
        print('2222')
    def f3(self):
        print('3333')

obj = Foo()
# getattr(obj, 'func')  在obj中寻找,与字符串'func'同名的函数,并返回
for i in range(1, 4):
    v = getattr(obj, 'f%s' % i)
    v()

# hasattr(obj, 'func')  判断obj中是否有,与字符串'func'同名的函数,并返回True/False
for i in range(4):
    print(hasattr(obj, 'f%s' % i))

# setattr(obj, 'name', value) 给obj中设置一个对象,名为'name'(字符串的形式), 值为value
# setattr 并不会改写代码,只是在内存中给对象添加,并不会影响到创建他的类
setattr(obj, 'age', 1000)
print(obj.age)

# delattr(obj, 'name')  把obj中名为'name'的成员删掉,并不会影响到创建他的类
delattr(obj, 'age')
print(hasattr(obj, 'age'))

4. 补充:

A. 可迭代对象的判断:

# 把一个类改为可迭代的,只需添加 __iter__方法
class Foo:
    def __iter__(self):
        yield 111
        yield 222
        yield 333

obj = Foo()
for i in obj:
    print(i)

 

posted @ 2019-07-07 23:28  Seawa  阅读(201)  评论(0)    收藏  举报