zoukankan      html  css  js  c++  java
  • 面向对象之组合的补充,主动调用其他类的成员,特殊成员

    一丶组合的补充

      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
    lib/aa.py
    from lib.aa import C
    
    obj = C()
    print obj.__module__  # 输出 lib.aa,即:输出模块
    print obj.__class__      # 输出 lib.aa.C,即:输出类
    index.py

      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'}
    View Code

      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__
    View Code

      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__
    View Code

     

  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/qicun/p/9555093.html
Copyright © 2011-2022 走看看