• 10、python全栈之路-面向对象进阶


    十、面向对象进阶

    http://www.cnblogs.com/Eva-J/articles/7351812.html

    1isinstanceissubclass

    1.1 isinstance(obj,cls)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

     

    1.2 issubclass(sub, super)

    issubclass(sub, super)检查sub类是否是 super 类的派生类

     

    2、反射

    #把一个字符串数据类型的变量变成一个真实存在在这个程序中的变量名,并且能够使用它

    #getattr是反射的灵魂

    #hasattegetattr是最佳cp

        #类名调属性或方法(静态()属性,静态方法和类方法)

        #对象名调属性或方法(对象属性,普通方法(self))

        #模块名调用属性或方法(变量,函数)

        #在自己模块中调用属性或方法(变量,函数)

            #自己的模块表示:sys.modules[__name__]

    ###setattr

    ####delattr

    2.1 getter()

    getattr(对象,'方法名或者属性名'),不通过调用类的方法,直接用这个函数来调用方法

     

    2.2 hasattr()

    hasattr(对象,'方法名或者属性名') 判断对象中是否存在这个方法或属性 返回布尔值

    如果方法不存在会报错,这时候就需要用到hasattr来做判断

     

    if hasattr(jinghong,'sleep'):
        func = getattr(jinghong,'sleep')
        func()

    2.3 setattr()

    设置属性

     

    2.4 delattr()

     

    2.5 类名调属性或方法

    静态()属性,静态方法和类方法

     

    2.6 对象名调属性或方法

    对象属性,普通方法(self

     

    2.7 模块名调用属性或方法

    变量,函数

     

    2.8 在自己模块中调用属性或方法

    变量,函数

    #自己的模块表示:sys.modules[__name__]

     

    3、类的内置方法

    #python的类的内置方法和内置函数还有其他函数都有千丝万缕的联系

    3.1 __str____repr__

    format_dict = {
        'nat': '{obj.name}-{obj.addr}-{obj.type}',  # 学校名-学校地址-学校类型
        'tna': '{obj.type}:{obj.name}:{obj.addr}',  # 学校类型:学校名:学校地址
        'tan': '{obj.type}/{obj.addr}/{obj.name}',  # 学校类型/学校地址/学校名
    }

    class School:
        def __init__(self, name, addr, type):
            self.name = name
            self.addr = addr
            self.type = type

        def __repr__(self):
            return 'School(%s,%s)' % (self.name, self.addr)

        def __str__(self):
            return '(%s,%s)' % (self.name, self.addr)

        def __format__(self, format_spec):
            # if format_spec
            if not format_spec or format_spec not in format_dict:
                format_spec = 'nat'
            fmt = format_dict[format_spec]
            return fmt.format(obj=self)

    s1 = School('oldboy1', '北京', '私立')
    print('from repr: ', repr(s1))
    print('from str: ', str(s1))
    print(s1)

    '''
    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1, 'nat'))
    print(format(s1, 'tna'))
    print(format(s1, 'tan'))
    print(format(s1, 'asfdasdffd'))

     

    class B:
        def __str__(self):
            return 'str : class B'

        def __repr__(self):
            return 'repr : class B'

    b = B()
    print('%s' % b)
    print('%r' % b)

     

    3.2 __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

     

    3.3 __getitem__\__setitem__\__delitem__

    class Foo:
        def __init__(self,name):
            self.name=name

        def __getitem__(self, item):
            print(self.__dict__[item])

        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)

    f1=Foo('sb')
    f1['age']=18
    f1['age1']=19
    del f1.age1
    del f1['age']
    f1['name']='alex'
    print(f1.__dict__)

     

    3.4 __new__

    3.4.1 __new__

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)

    a = A()
    print(a.x)

     

    class Singleton:
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance

    one = Singleton()
    two = Singleton()

    two.a = 3
    print(one.a)
    # 3
    # one和two完全相同,可以用id(), ==, is检测
    print(id(one))
    # 29097904
    print(id(two))
    # 29097904
    print(one == two)
    # True
    print(one is two)

     

    3.4.2 单例模式

    #单例模式  实例始终只有一个 他的属性可以随着你的改变而改变

    class Teacher:               #创建一个老师类
        __isinstance = None      #创建一个私有静态变量来装裸着的对象
        def __new__(cls, *args, **kwargs):   #创建一个裸着的对象
            if not cls.__isinstance:         #如果__isinstance属性为None
                cls.__isinstance = object.__new__(cls)   #用object.__new__创建一个裸着的对象
            return cls.__isinstance          #返回一个对象

        def __init__(self,name,cloth):       #self就是cls.__isinstance返回的对象
            self.name = name                 #给self的name属性赋值
            self.cloth = cloth               #给self的cloth属性赋值

    刘老师 = Teacher('刘永熹','白色')
    print(刘老师.name)
    王老师 = Teacher('王庆帅','黑色')
    王老师2 = Teacher('王庆帅','黑色')
    王老师3 = Teacher('王庆帅','黑色')
    王老师4 = Teacher('王庆帅','黑色')
    print(刘老师.name)
    print(王老师)
    print(王老师2)
    print(王老师3)
    print(王老师4)

     

    3.5 __call__

    对象后面加括号,触发执行。

    class Foo:
        def __init__(self):
            pass

        def __call__(self, *args, **kwargs):
            print('__call__')

    obj = Foo()  # 执行 __init__
    obj()  # 执行 __call__

     

    3.6 __len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2

        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))

     

    3.7 __hash__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2

        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    a = A()
    print(hash(a))

     

    3.8 __eq__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2

        def __eq__(self,obj):
            if  self.a == obj.a and self.b == obj.b:
                return True
    a = A()
    b = A()
    print(a == b)

     

    3.9 面试题

    #     有一个类的init方法如下:

    #     class Person

    #         def __init__(self,name,age,sex,weight):

    #             self.name = name

    #             self.sex = sex

    #             self.age = age

    #             self.weight = weight

    #     假设有100person的对象,

    #     若两个对象的obj1,obj2namesex属性相同

    #     obj1.name==obj2.name and obj1.sex==obj2.sex

    #     我们认为两个对象为同一个对象,已知一个列表中的100个对象,对这100个对象进行去重。

    #     提示:

    #         重写Person类重的两个内置方法

    class Person:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age

        def __hash__(self):
            return hash(self.name+self.sex)

        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:
                return True
    obj_lst = []
    for i in range(100):
        obj_lst.append(Person('liquan','male',i))
    print(obj_lst)
    print(set(obj_lst))   #unhashable

  • 相关阅读:
    Codeforces Gym
    洛谷试炼场一句话题解
    优先队列板子
    BZOJ 3524 [POI2014] Couriers/洛谷3567(可持久化线段树)
    hdu 4417 Super Mario(可持久化线段树)
    poj 2559 Largest Rectangle in a Histogram (单调栈)
    zoj 4019 Schrödinger's Knapsack
    hdu 1521 排列组合(指数型生成函数板子)
    hdu 2072 单词数(普通型生成函数板子)
    RabbitMQ广播:direct模式
  • 原文地址:https://www.cnblogs.com/xiaojinyu/p/7581591.html
Copyright © 2020-2023  润新知