面对对象相关
一,特殊成员的补充
对象名.__dict__ 查看对象内的实例变量
class Foo(object): def __init__(self,name,age): self.name = name self.age = age def func(self): pass obj1 = Foo('刘博文',99) obj2 = Foo('史雷',89) print(obj1.__dict__) # {'name': '刘博文', 'age': 99} print(obj2.__dict__) # {'name': '史雷', 'age': 89} print(Foo.__dict__) # {'name': '史雷', 'age': 89} #{'__module__': '__main__', '__init__': <function Foo.__init__ at 0x006884F8>, 'func': <function Foo.func at 0x00688540>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__'\ # : <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
如果想要把不可迭代队象 转化为 可迭代对象
执行两步 1 在类中定义__iter__方法
2 在iter 内部返回一个迭代器(生成器是特殊的迭代器)
举例如下
class Foo(object): def __init__(self,name,age): self.name = name self.age = age # obj1 = Foo('刘博文',99) # obj2 = Foo('史雷',89) # for i in obj1: # print(i) #报错'Foo' object is not iterable # 那我们在类里面定义一个__iter方法 class Foo(object): def __init__(self,name,age): self.name = name self.age = age def __iter__(self): # return iter([1,2,3,4]) #yield和return 选择一个就可以了 yield 99 yield 88 yield 77 obj1 = Foo('刘博文',99) obj2 = Foo('史雷',89) for i in obj1: print(i) #1 2 3 4 yield 换成 99 88 77
二, 面对象相关
issubclass
举个例子如下
class Base(object): pass class Foo(Base): pass class Bar(Foo): pass print(issubclass(Bar,Base)) # True 检查第一个参数是否是第二个参数的 子子孙孙类
isinstance
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)) # False检查第一个参数(对象)是否是第二个参数(类及父类)的实例。 print(isinstance(obj2,Base)) # True检查第一个参数(对象)是否是第二个参数(类及父类)的实例。
type
class Foo(object): pass obj = Foo() print(obj,type(obj)) # <__main__.Foo object at 0x004ADD10> <class '__main__.Foo'>获取当前对象是由那个类创建。 if type(obj) == Foo: print('obj是Foo类型') print(type(obj) == Foo)#True print(1==2)#False
下面举个例子用函数判断函数类型
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)
三 用科学方法判断是函数还是方法
from types import MethodType,FunctionType def check(arg): """ 检查arg是方法还是函数? :param arg: :return: """ if isinstance(arg,MethodType): print('arg是一个方法') elif isinstance(arg,FunctionType): print('arg是一个函数') else: print('不知道是什么')
class Foo(object): def f1(self): pass def f2(self): pass def f3(self): pass # obj = Foo() # print(obj.f1) # print(obj.f2) obj = Foo() Foo.f1(obj) # 把f1当做函数 这个obj对象就要自己传 obj = Foo() obj.f1() # 把f1当做方法,自动传self值
四 反射
1,在模块中
#handler文件 #####
def f1():
print('F1')
def f2():
print('F2')
def f3():
print('F3')
def f4():
print('F4')
def f5():
print('F5')
#run 文件
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中不存在输入的属性名')
下面是比较笨的方法
"""
if val == 'f1':
handler.f1()
elif val == 'f2':
handler.f2()
elif val == 'f3':
handler.f3()
elif val == 'f4':
handler.f4()
elif val == 'f5':
handler.f5()
2,在类和对象中
class Foo(object): country = "中国" def func(self): pass v = getattr(Foo,'func') # Foo.func # 根据字符串为参数,去类中寻找与之同名的成员。 print(v) obj = Foo() v = getattr(obj,"func") # obj.func # 根据字符串为参数,去对象中寻找与之同名的成员。 print(v)
3,反射补充
""" getattr # 根据字符串的形式,去对象或是类或是模块中找成员。 hasattr # 根据字符串的形式,去判断对象中是否有成员。 setattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存) 与文件没有关系 delattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存) 与文件没有关系 """
###xxx.py####
x1 = 123
def f1(arg):
print(arg,666)
###反射补充.py####
import xx # getattr v1 = getattr(xx,'x1') v2 = getattr(xx,'f1') v2('杨森') # hasattr v3 = hasattr(xx,'x1') #True v4 = hasattr(xx,'f1') #True
v5 = hasattr(xx,'xxxxxxx') print(v3,v4,v5) #False
# setattr setattr(xx,'x2',999) #设置一个x2 = 1 的实例变量.但是存在内存里了,与文件没有关系
v6 = getattr(xx,'x2') #True
print(v6)
setattr(xx,'f2',lambda x:x+1)
v7 = getattr(xx,'f2')
v8 = v7(1) print(v8)
# delattr delattr(xx,'x1') #删除一个实例变量
v9 = getattr(xx,'x1') #False
print(v9)
class Foo(object): def __init__(self,a1): self.a1 = a1 self.a2 = None obj = Foo(1) v1 = getattr(obj,'a1') print(v1) setattr(obj,'a2',2) v2 = getattr(obj,'a2') print(v2)
实例
# 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()
#类似的第二种方法,把run函数单独拿出来
class Account(object): def login(self): """ 登录 :return: """ print('登录111') def logout(self): """ 注销 :return: """ print('注销111') def register(self): """ 注册 :return: """ print('注册111') obj1 = Account() func_list = ['login', 'logout', 'register'] def run(): """ 主代码 :return: """ print(""" 请输入要执行的功能: 1. 登录 2. 注销 3. 注册 """) choice = int(input('请输入要执行的序号:')) func_name =func_list[choice - 1] # func = getattr(Account, func_name) # self.login # func(obj1) 此处用不了self func = getattr(obj1, func_name) # self.login func() run()

浙公网安备 33010602011771号