类的相关内置函数及反射

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

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 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()
练习

 


posted @ 2018-08-30 20:14  张大仙er  阅读(279)  评论(0编辑  收藏  举报