面向对象之组合的补充,主动调用其他类的成员,特殊成员
程序员文章站
2023-09-28 14:58:43
一丶组合的补充 1.类或对象是否能做字典的key? 2.对象中到底有什么呢? 解析:为什么最后会带一个None呢? 因为display方法并没有返回值,但是默认返回值是None,所以当调用完display后会默认返回一个None. 3.把三个对象放入一个列表, 解析:列表中存放着的是对象,当用for ......
一丶组合的补充
1.类或对象是否能做字典的key?
class foo: pass user_info = { foo:1, foo():5 } print(user_info) #{<class '__main__.foo'>: 1, <__main__.foo object at 0x000002cf8b1a9cf8>: 5}
2.对象中到底有什么呢?
class foo(object): def __init__(self,age): self.age = age def display(self): print(self.age) data_list = [foo(8),foo(9)] for item in data_list: print(item.age,item.display())
解析:为什么最后会带一个none呢? 因为display方法并没有返回值,但是默认返回值是none,所以当调用完display后会默认返回一个none.
3.把三个对象放入一个列表,
class starkconfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) class roleconfig(starkconfig): def changelist(self,request): print('666') # 创建了一个列表,列表中有三个对象(实例) # [ starkconfig对象(num=1), starkconfig对象(num=2), roleconfig对象(num=3) ] config_obj_list = [starkconfig(1),starkconfig(2),roleconfig(3)] for item in config_obj_list: print(item.num)
# 1 2 3
解析:列表中存放着的是对象,当用for依次拿出来时调用num,starkconfig直接把括号里面的传给num,roleconfig(3)调用时先找自己类里面是否有num,没有就去父类里面找,把括号里的传给父类里面的num,输出num.
4.示例
class starkconfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) class roleconfig(starkconfig): def changelist(self,request): print(666,self.num) # 创建了一个列表,列表中有三个对象(实例) # [ starkconfig对象(num=1), starkconfig对象(num=2), roleconfig对象(num=3) ] config_obj_list = [starkconfig(1),starkconfig(2),roleconfig(3)] for item in config_obj_list: item.changelist(168)
#1 168
#2 168
#666 3
解析:跟3有异曲同工之妙,item.changelist(168) 相当于 starkconfig(1).changelist(168),也就是用对象来调用类中的方法,两个starkconfig直接把对象中的值传给num,changelist中的值传给request,输出为1,168.而roleconfig对象在自己类中找不到num,于是去基类(父类)里面找,然后把3赋给num,然后在自己类里找changelist,把168传给request,但是在输出时,输出的是666,跟num,并未输出request,所以最后结果为666,3
5丶
class starkconfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class roleconfig(starkconfig): def changelist(self,request): print(666,self.num) class adminsite(object): def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v site = adminsite() site.register('lyd',starkconfig(19)) site.register('yjl',starkconfig(20)) site.register('fgz',roleconfig(33)) print(len(site._registry)) # 3 for k,row in site._registry.items(): row.changelist(5)
解析:先将'lyd',starkconfig(19) 等这三个加入字典,for循环中把字典中的value赋给row,然后通过row调用changelist,前两个starkconfig先把对象里的数赋给num,然后再找类中的changelist方法,把5传给request,输出的是num 的值跟request的值,而roleconfig先在自己类中找num,找不到后去基类(父类)starkconfig中找,把对象中的数传给num,然后再在自己类中找changelist方法,然后 把5传给request,输出为666,跟基类中的num的值
6丶
class userinfo(object): pass class department(object): pass class starkconfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class roleconfig(starkconfig): def changelist(self,request): print(666,self.num) class adminsite(object): def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v(k) site = adminsite() site.register(userinfo,starkconfig) site.register(department,starkconfig) print(len(site._registry)) for k,row in site._registry.items(): row.run()
解析:向字典中传的key为userinfo跟department,value为starkconfig(userinfo)和starkconfig(department),所以print输出的长度为2,然后再for循环出来value调用,把userinfo和department这两个类当做参数传给了num,然后再调用run方法,通过run方法再调用changelist方法,把999传给request,输出的就是userinfo和department两个类跟999
注意;以上几个题要注意调用的是哪个方法,self是哪个类中的.不要转晕了
二丶主动调用其他类的成员
方式一丶
class base(object): def f1(self): print('5个功能') class foo(object): def f1(self): print('3个功能') base.f1(self) obj = foo() obj.f1()
解析:当调用类foo中的f1方法时,f1方法中也存在着调用类base中f1的语句,所以调用类foo中的f1也相当于调用了类base
方式二丶按照类的继承顺序,找下一个.
class foo(object): def f1(self): super().f1() print('3个功能') class bar(object): def f1(self): print('6个功能') class info(foo,bar): pass obj = info() obj.f1()
解析:通过类的继承顺序,依次查找下一个
三丶特殊成员
1.__init__ 构造方法,通过类创建对象时,自动触发执行。
class foo: def __init__(self, name): self.name = name self.age = 18 obj = foo('迪迦') # 自动执行类中的 __init__ 方法
2.__call__ 对象后面加括号,触发执行。
class foo: def __init__(self): pass def __call__(self, *args, **kwargs): print '__call__' obj = foo() # 执行 __init__ obj() # 执行 __call__
3.__getitem__ 对[xxx"] 自动执行
class foo(object): def __getitem__(self, item): print(item) return 8 obj = foo() ret = obj['yu'] print(ret)
4.__setitem__ 对象[xxx"] = 11 自动执行
class foo(object): def __setitem__(self, key, value): print(key, value, 111111111) obj = foo() obj['k1'] = 123
5.del 对象[xxx] 自动执行 __delitem__
class foo(object): def __delitem__(self, key): print(key) obj = foo() del obj['uuu']
6.对象+对象 自动执行 __add__
class foo(object): def __init__(self, a1, a2): self.a1 = a1 self.a2 = a2 def __add__(self, other): return self.a1 + other.a2 obj1 = foo(1,2) obj2 = foo(88,99) ret = obj2 + obj1 print(ret)
7.with 对象 自动执行__enter__/__exit__
class foo(object): def __init__(self, a1, a2): self.a1 = a1 self.a2 = a2 def __enter__(self): print('1111') return 999 def __exit__(self, exc_type, exc_val, exc_tb): print('22222') obj = foo(1,2) with obj as f: print(f) print('内部代码')
8. __module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
#!/usr/bin/env python # -*- coding:utf-8 -*- class c: def __init__(self): self.name = 'wupeiqi' lib/aa.py
from lib.aa import c obj = c() print obj.__module__ # 输出 lib.aa,即:输出模块 print obj.__class__ # 输出 lib.aa.c,即:输出类
9.__doc__ 表示类的描述信息
class foo: """ 描述类信息,这是用于看片的神奇 """ def func(self): pass print foo.__doc__ #输出:类的描述信息
10.__del__
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class foo: def __init__(self): pass def __call__(self, *args, **kwargs): print '__call__' obj = foo() # 执行 __init__ obj() # 执行 __call__
11.__dict__
类或对象中的所有成员
上文中我们知道:类的普通字段属于对象;类中的静态字段和方法等属于类,即:
class province: country = 'china' def __init__(self, name, count): self.name = name self.count = count def func(self, *args, **kwargs): print 'func' # 获取类的成员,即:静态字段、方法、 print province.__dict__ # 输出:{'country': 'china', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': none} obj1 = province('hebei',10000) print obj1.__dict__ # 获取 对象obj1 的成员 # 输出:{'count': 10000, 'name': 'hebei'} obj2 = province('henan', 3888) print obj2.__dict__ # 获取 对象obj1 的成员 # 输出:{'count': 3888, 'name': 'henan'}
12.__str__
如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class foo: def __str__(self): return 'wupeiqi' obj = foo() print obj # 输出:wupeiqi
13. __iter__
用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
# __iter__ # l1是list类的一个对象,可迭代对象 l1 = [11,22,33,44] # l2是list类的一个对象,可迭代对象 l2 = [1,2,3,4] class foo: def __init__(self,name,age): self.name = name self.age = age def func(self): pass def __iter__(self): return iter([11,22,33,44,55,66,7]) # 或 # yield 123 # yield 456 # yield 789 # obj1是foo类的一个对象,可迭代对象 """ 如果想要把不可迭代对象 -> 可迭代对象 1. 在类中定义__iter__方法 2. iter内部返回一个迭代器(生成器也是一种特殊迭代器) """ obj = foo('盖伦',23) for item in obj: print(item) 结果: 22 44 66 __iter__
14.__new__ 真正的构造方法
class foo(object): def __init__(self, a1, a2): # 初始化方法 """ 为空对象进行数据初始化 :param a1: :param a2: """ self.a1 = a1 self.a2 = a2 def __new__(cls, *args, **kwargs): # 构造方法 """ 创建一个空对象 :param args: :param kwargs: :return: """ return object.__new__(cls) # python内部创建一个当前类的对象(初创时内部是空的.). obj1 = foo(1,2) print(obj1) obj2 = foo(11,12) print(obj2) 真正的构造方法__new__
15.真正的构造方法
class foo(object): def __init__(self, a1, a2): # 初始化方法 """ 为空对象进行数据初始化 :param a1: :param a2: """ self.a1 = a1 self.a2 = a2 def __new__(cls, *args, **kwargs): # 构造方法 """ 创建一个空对象 :param args: :param kwargs: :return: """ return object.__new__(cls) # python内部创建一个当前类的对象(初创时内部是空的.). obj1 = foo(1,2) print(obj1) obj2 = foo(11,12) print(obj2)