day24

1. 组合(嵌套)的补充
练习题(10道)
# ###1. 类或者对象是否能做字典的key
class Foo:
    pass

user_info = {
    Foo: 1,
    Foo(): 5
}

print(user_info)

# ### 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())
# 答案:
        8
        8 None
        9
        9 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

# ### 4.
class StarkConfig(object):

    def __init__(self, num):
        self.num = num

    def changelist(self, request):
        print(self.num, request)

class RoleConfig(StarkConfig):
    pass

# 创建了一个列表,列表中有三个对象(实例)
# RoleConfig(3) 被创建时需要执行构造方法,自己没有,就从父类里去找,使用父类的构造方法创建自己的变量num=3
# [ 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  3 168

# ### 5.
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)

# 创建了一个列表,列表中有三个对象(实例)
# RoleConfig(3) 被创建时需要执行构造方法,自己没有,就从父类里去找,使用父类的构造方法创建自己的变量num=3
# [ 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

# ### 6.
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)

config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)]
config_obj_list[1].run()
config_obj_list[2].run()  # 666 3

# ### 7.
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()
print(len(site._registry))  # 0
site.register('boshao', 666)
site.register('donggua', 438)
print(len(site._registry))  # 2

site.register('lx', StarkConfig(19))
site.register('magic', StarkConfig(20))
site.register('lzz', RoleConfig(33))
print(len(site._registry))  # 5

### 8.
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('lx', StarkConfig(19))
site.register('magic', StarkConfig(20))
site.register('lzz', RoleConfig(33))
print(len(site._registry))  # 3

for k, row in site._registry.items():
    row.changlist(5)

# 答案: 19 5  20 5  666 33

# ### 9.
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('lx', StarkConfig(19))
site.register('magic', StarkConfig(20))
site.register('lzz', RoleConfig(33))
print(len(site._registry))  # 3

for k, row in site._registry.items():
    row.run()

# 答案: 19 999  20 999  666 33

# ### 10.
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))  # 2
for k, row in site._registry.items():
    row.run()

# 答案: 类UserInfo 999  类Department 999

* 总结
    1. 对象中封装了什么?
    2. self到底是谁?

2. 主动调用其他类的成员

# 方式一: 通过类名调用, 但是需要手动传参
class Base(object):

    def f1(self):
        print('5个功能')

class Foo(object):

    def f1(self):
        print('3个功能')
        Base.f1(self)

obj = Foo()
obj.f1()

# 总结:
    # Base.实例方法(自己传self)
    # 与继承无关


# 方式二: 按照类的继承顺序, 找下一个
class Foo(object):
    def f1(self):
        super().f1()  # 去原点找,按照类的继承顺序,找当前类的下一个
        print('3个功能')

class Bar(object):
    def f1(self):
        print('6个功能')

class Info(Foo, Bar):
    pass

# obj = Foo()
# obj.f1()  报错

obj = Info()
obj.f1()

# 总结:
    # super()的用法是个易错点, 按照类的继承顺序, 找当前类的下一个

3. 特殊成员

class Foo(object):

    def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
        
    def __call__(self, *args, **kwargs):
        print(11111, args, kwargs)
        return 123

    def __getitem__(self, item):
        print(item)
        return 8

    def __setitem__(self, key, value):
        print(key, value, 11111111)

    def __delitem__(self, key):
        print(key)

    def __add__(self, other):
        return self.a1 + other.a2

    def __enter__(self):
        print('111')
        return 999

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(22222)

# 1. 类名()  自动执行 __init__
obj = Foo(1, 2)

# 2. 对象()  自动执行 __call__
ret = obj(6, 4, 2, k1=456)
print(ret)

# 3. 对象['xx']     自动执行 __getitem__
ret = obj['yu']
print(ret)

# 4. 对象['xx'] = 11  自动执行 __setitem__
obj['k1'] = 123  # 不能有返回值

# 5. del 对象[xx]     自动执行 __delitem__
del obj['uuu']  # 不能有返回值

# 6. 对象+对象         自动执行 __add__
obj1 = Foo(1, 2)
obj2 = Foo(88, 99)
ret = obj2 + obj1
print(ret)

# 7. with 对象
obj = Foo(1, 2)     # 自动执行 __enter__ / __exit__
with obj as f:
    print(f)
    print('内部代码')
# 8. 真正的构造方法
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内部创建一个当前类的对象(初创时内部是空的).

obj = Foo(1, 2)  # 在实例化对象时:类名+(), 先执行__new__方法,创建并返回一个空对象,才能继续执行__init__方法,为空对象进行数据的初始化.
print(obj)
# 补充
__str__
    (1) 当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
    (2) __str__方法需要返回一个字符串,当做这个对象的描写
示例:
    class Foo(object):
        def __init__(self):
            pass

        def func(self):
            pass

        def __str__(self):
            return 'F1'

    obj = Foo()
    print(obj, type(obj))


__doc__: 类/对象.__doc__, 获取类/对象的注释介绍
class Foo(object):
    """
    afsdafsdgddsafas
    """
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return 'F1'

obj = Foo()
print(obj.__doc__)


__dict__: 对象.__dict__, 自动存储成员信息(字典),并获取
示例:
    class Foo(object):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def func(self):
            pass
    
    obj1 = Foo('刘博文', 99, '')
    obj2 = Foo('史雷', 89)
    
    print(obj1.__dict__)  # {'name': '刘博文', 'age': 99}
    print(obj2.__dict__)  # {'name': '史雷', 'age': 89}


__iter__
# l1是list类的一个对象,可迭代对象
l1 = [11, 22, 33, 44]

# l2是list类的一个对象,可迭代对象
l2 = [1, 22, 3, 44]

示例:
    class Foo(object):
        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])
            yield 11
            yield 22
            yield 33
    
    # obj1是Foo类的一个对象, 可迭代对象
    """
    如果想要把不可迭代对象 -> 可迭代对象
    1. 在类中定义__iter__方法
    2. iter内部返回一个迭代器(生成器也是一种特殊迭代器)
    """
    obj1 = Foo('刘博文', 99)
    
    for item in obj1:
        print(item)


原文地址:https://www.cnblogs.com/kangqi452/p/11578826.html