类的相关内置函数及反射

Posted --kai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的相关内置函数及反射相关的知识,希望对你有一定的参考价值。

类变量的内存位置相关练习

1.1

技术分享图片
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
练习1

技术分享图片

1.2

技术分享图片
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()
s2 = StarkConfig()

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

result2 = s2.get_list_display()
print(result2) # [33,33]
练习2

技术分享图片

1.3

技术分享图片
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()
s2 = RoleConfig()

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

result2 = s2.get_list_display()
print(result2)            # [33,11,22]
练习3

技术分享图片

类的相关内置函数

 1.1 issubclass(参数1,参数2)

检查第一个参数是否是第二个参数的子类及子类的子类(比较圆滑,只要是长辈都返回True),返回True和Flase,可以判断对象是不是由某一个指定类或其父类

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


class Foo(Base):
    pass


class Bar(Foo):
    pass


print(issubclass(Foo, Base))
print(issubclass(Foo, object))
print(issubclass(Bar, Foo))
print(issubclass(Bar, Base))
print(issubclass(Bar, object))

# 输出结果:
True
True
True
True
True
View Code

1.2 type

获取当前对象是由哪个类创建,只承认当前对象的直接上级(比较死板),可以判断对象是不是由某一个指定类创建

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

obj = Foo()

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

# 输出结果:
<__main__.Foo object at 0x00000272D5EB6320> <class __main__.Foo>

# 可以人为判断

if type(obj) == Foo:
    print(obj是Foo类型)

# 因判断为True
# 输出结果:
obj是Foo类型
View Code

1.3 isinstance(对象,类)

检查第一个参数(对象)是否是第二个参数(类及父类)的实例,返回True和Flase

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

    def f1(self):
        pass

    def f2(self):
        pass

    def f3(self):
        pass

obj = Foo()
Foo.f1(obj) # 把f1当做函数

obj = Foo()
obj.f1()    # 把f1当做方法,自动传self值
View Code
技术分享图片
class Base(object):
    pass

class Foo(Base):
    pass

obj1 = Foo()

print(isinstance(obj1,Foo)) # True
print(isinstance(obj1,Base)) #True     由此可见是其父类也返回True

obj2 = Base()
print(isinstance(obj2,Foo))  #Flase      由此可见,是其子类不可以,返回Flase
View Code

用科学的方法判断是函数还是方法

我们一般认为,写在类中的就可以叫做方法,写在外面的就可以叫做函数

科学的方法判断就是判断它是不是方法类或函数类中的,因为在python中,一切皆对象,方法和函数也是某个类的对象

MethodType(方法),FunctionType(函数)

技术分享图片
from types import MethodType,FunctionType
def check(arg):
    """
    检查arg是方法还是函数?
    :param arg:
    :return:
    """
    if isinstance(arg,MethodType): # 如果arg是MethodType类的实例

        print(arg是一个方法)
    elif isinstance(arg,FunctionType): # 如果arg是FunctionType类的实例
        print(arg是一个函数)
    else:
        print(不知道是什么)

def func():
    pass

class Foo(object):
    def detail(self): # 默认传入self参数
        pass
    @staticmethod
    def xxx(): # 没有默认参数
        pass


check(func) #这是一个函数
obj = Foo()
check(obj.detail) # 这是一个方法
check(obj.xxx)  # 这是一个函数

"""
由上述可知,判断是方法还是函数,也看有没有其怎么调用或是否有默认self参数传入
"""
View Code

小结:

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

类.xxx --> xxx就是函数

xxx --> xxx就是函数

反射

geattr(对象,字符串)

根据字符串为参数,去对象中寻找与之同名的成员

去模块中寻找

技术分享图片
"""
建立一个handler.py文件

"""
f0 = 9

def f1():
    print(F1)

def f2():
    print(F2)

def f3():
    print(F3)

def f4():
    print(F4)

def f5():
    print(F5)

"""
同目录级引入上述handler模块

"""

import handler

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

    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

面向对象中用geattr

技术分享图片
 1 class Foo(object):
 2 
 3     country = "中国"
 4 
 5     def func(self):
 6        pass
 7 
 8 v = getattr(Foo,func) # Foo.func # 根据字符串为参数,去类中寻找与之同名的成员。
 9 print(v) # 输出fun的内存地址,通过类查找,此时 func是个函数
10 
11 obj = Foo()
12 v = getattr(obj,"func") # obj.func # 根据字符串为参数,去对象中寻找与之同名的成员。
13 print(v)  # 输出func的内存地址,通过对象查找,此时func是个方法
反射简单示例

hasattr

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

技术分享图片
import xx

v3 = hasattr(xx,x1)
v4 = hasattr(xx,f1)
v4 = hasattr(xx,f1)
v5 = hasattr(xx,xxxxxxx)
print(v3,v4,v5)
 # True True False
View Code

setattr

根据字符串的形式,去判断对象中动态的设置一个成员(在内存中)

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

    def __init__(self,a1):
        self.a1 = a1
        self.a2 = None

obj = Foo(1)


v1 = getattr(obj,a1)
print(v1) # 1

setattr(obj,a2,2)    # 若__init__没有a2参数,不建议这么写,因为没有人知道你其中还有其    
                              # 他参数   若想写,最好在__init__那添加 a2 = None
v2 = getattr(obj,a2)
print(v2)  # 2                                    
View Code

delattr

根据字符串的形式,去判断对象中动态的设置一个成员(内存中)

技术分享图片
import xx

delattr(xx,x1)
v9 = getattr(xx,x1)
print(v9)
# 因删除了 x1 所以会报错

# AttributeError: module ‘xx‘ has no attribute ‘x1‘
View Code

getattr的实际应用

技术分享图片
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()
练习

 

 



以上是关于类的相关内置函数及反射的主要内容,如果未能解决你的问题,请参考以下文章

反射(高大上)类的内置方法

面向对象结构与成员(特殊成员)及相关内置函数

绑定与非绑定方法及反射,isinstance和issubclass内置函数

14 isinstance type issubclass及反射

Java反射机制及IoC原理

Java反射机制及IoC原理