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

     

  • 相关阅读:
    二进制插入 牛客网 程序员面试金典 C++ Python java
    二进制小数 牛客网 程序员面试金典 C++ Python
    二叉树中和为某一值的路径 牛客网 程序员面试金典 C++ Python
    Python matplotlib pylab 画张图
    Python matplotlib pylot和pylab的区别
    Ubuntu 16.04 curl 安装 使用
    Ubuntu 16.04 菜单栏 换位置 挪到左边 挪到下边
    Python 模块feedparser安装使用
    Ubuntu 16.04 下 旋转显示器屏幕 竖屏显示
    从 callback 到 promise
  • 原文地址:https://www.cnblogs.com/qicun/p/9555093.html
Copyright © 2011-2022 走看看