类变量的内存位置相关练习
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.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]
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]
类的相关内置函数
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
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类型
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
用科学的方法判断是函数还是方法
我们一般认为,写在类中的就可以叫做方法,写在外面的就可以叫做函数
科学的方法判断就是判断它是不是方法类或函数类中的,因为在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参数传入 """
小结:
对象.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中不存在输入的属性名')
面向对象中用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
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
delattr
根据字符串的形式,去判断对象中动态的设置一个成员(内存中)
import xx delattr(xx,'x1') v9 = getattr(xx,'x1') print(v9) # 因删除了 x1 所以会报错 # AttributeError: module 'xx' has no attribute 'x1'
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()