美文网首页
17、python面向对象进阶

17、python面向对象进阶

作者: go以恒 | 来源:发表于2018-09-26 11:52 被阅读0次

    面向对象进阶

    isinstance和issubclass

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

    class Foo(object):

        pass 

    obj = Foo()

    isinstance(obj, Foo)

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

    class Foo(object):

        pass class Bar(Foo):

        pass

    issubclass(Bar, Foo)

    反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    def hasattr(*args, **kwargs): # real signature unknown    """

        Return whether the object has an attribute with the given name.

        This is done by calling getattr(obj, name) and catching AttributeError.

        """    pass

    以下实例展示了 hasattr 的使用方法:

    #!/usr/bin/python# -*- coding: UTF-8 -*- class Coordinate:

        x = 10    y = -5    z = 0 point1 = Coordinate() print(hasattr(point1, 'x'))print(hasattr(point1, 'y'))print(hasattr(point1, 'z'))print(hasattr(point1, 'no'))  # 没有该属性

    def getattr(object, name, default=None): # known special case of getattr    """

        getattr(object, name[, default]) -> value

        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.

        When a default argument is given, it is returned when the attribute doesn't

        exist; without it, an exception is raised in that case.

        """    pass

    以下实例展示了 getattr 的使用方法:

    >>>class A(object):

    ...    bar = 1...

    >>> a = A()>>> getattr(a, 'bar')        # 获取属性 bar 值1>>> getattr(a, 'bar2')      # 属性 bar2 不存在,触发异常Traceback (most recent call last):

      File "<stdin>", line 1, in <module>AttributeError: 'A' object has no attribute 'bar2'>>> getattr(a, 'bar2', 3)    # 属性 bar2 不存在,但设置了默认值3

    def setattr(x, y, v): # real signature unknown; restored from __doc__    """

        Sets the named attribute on the given object to the specified value.

        setattr(x, 'y', v) is equivalent to ``x.y = v''

        """    pass

    以下实例展示了 setattr() 函数的使用方法:

    实例一

    >>>class A(object):

    ...    bar = 1...

    >>> a = A()>>> getattr(a, 'bar')          # 获取属性 bar 值1>>> setattr(a, 'bar', 5)      # 设置属性 bar 值>>> a.bar5

    实例二

    def delattr(x, y): # real signature unknown; restored from __doc__    """

        Deletes the named attribute from the given object.

        delattr(x, 'y') is equivalent to ``del x.y''

        """    pass

    以下实例展示了 delattr 的使用方法:实例一class Coordinate:

        x = 10    y = -5    z = 0 point1 = Coordinate()

    print('x = ',point1.x)print('y = ',point1.y)print('z = ',point1.z) delattr(Coordinate, 'z') print('--删除 z 属性后--')print('x = ',point1.x)print('y = ',point1.y) # 触发错误print('z = ',point1.z)

    实例二

    class Foo:

        f = '类的静态变量'    def __init__(self,name,age):

            self.name=name

            self.age=age

        def say_hi(self):

            print('hi,%s'%self.name)

    obj=Foo('egon',73)#检测是否含有某属性print(hasattr(obj,'name'))print(hasattr(obj,'say_hi'))#获取属性n=getattr(obj,'name')print(n)

    func=getattr(obj,'say_hi')

    func()print(getattr(obj,'aaaaaaaa','不存在啊')) #报错#设置属性setattr(obj,'sb',True)

    setattr(obj,'show_name',lambda self:self.name+'sb')print(obj.__dict__)print(obj.show_name(obj))#删除属性delattr(obj,'age')

    delattr(obj,'show_name')

    delattr(obj,'show_name111')#不存在,则报错print(obj.__dict__)

    实例三

    class Foo(object):

        staticField = "old boy"

        def __init__(self):

            self.name = 'wupeiqi'

        def func(self):

            return 'func'

        @staticmethod

        def bar():

            return 'bar' print getattr(Foo, 'staticField')  #获取到属性值print getattr(Foo, 'func') #获取到func的地址print getattr(Foo, 'bar')

    实例四

    import sys

    def s1():

        print 's1'def s2():

        print 's2'this_module = sys.modules[__name__]

    hasattr(this_module, 's1')

    getattr(this_module, 's2')

    导入其他模块,利用反射查找该模块是否存在某个方法

    def test():

        print('from the test')

    """

    程序目录:

        module_test.py

        index.py

    当前文件:

        index.py

    """import module_test as obj#obj.test()print(hasattr(obj,'test'))

    getattr(obj,'test')()

    __str__和__repr__

    改变对象的字符串显示__str__,__repr__

    自定制格式化字符串__format__

    #_*_coding:utf-8_*_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)

    __del__

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

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class Foo:

        def __del__(self):

            print('执行我啦')

    f1=Foo()del f1print('------->')#输出结果执行我啦

    ------->

    item系列

    __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

            print("f1['age']=18时,我执行")

        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')

    # __dict__[item] 内部是以字典的形式保存数据

    # __setitem__设置 key, value

    f1['age']=18

    f1['age1']=19

    # __getitem__ 输出设置的值

    print(f1.age) 

    # __delattr__ 根据Key删除设置的属性

    del f1.age1

    # __delitem__ 根据value删除设置的属性

    del f1['age']

    f1['name']='alex'

    print(f1.__dict__)

    __new__

    View Code

    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'):

                cls._instance = object.__new__(cls, *args, **kw)

            return cls._instance

    one = Singleton()

    two = Singleton()

    two.a = 3print(one.a)# 3

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

    __call__

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

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class Foo:

        def __init__(self):

            pass   

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

            print('__call__')

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

    __len__

    class A:

        def __init__(self):

            self.a = 1

            self.b = 2

        def __len__(self):

            return len(self.__dict__)

    a = A()print(len(a))

    __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))

    __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)

    纸牌游戏

    from collections import namedtuple

    Card = namedtuple('Card',['rank','suit'])

    class FranchDeck:

        ranks = [str(n) for n in range(2,11)] + list('JQKA')

        suits = ['红心','方板','梅花','黑桃']

        def __init__(self):

            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks

                                            for suit in FranchDeck.suits]

        def __len__(self):

            return len(self._cards)

        def __getitem__(self, item):

            return self._cards[item]

    deck = FranchDeck()print(deck[0])from random import choiceprint(choice(deck))print(choice(deck))

    纸牌游戏2

    from collections import namedtuple

    Card = namedtuple('Card',['rank','suit'])

    class FranchDeck:

        ranks = [str(n) for n in range(2,11)] + list('JQKA')

        suits = ['红心','方板','梅花','黑桃']

        def __init__(self):

            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks

                                            for suit in FranchDeck.suits]

        def __len__(self):

            return len(self._cards)

        def __getitem__(self, item):

            return self._cards[item]

        def __setitem__(self, key, value):

            self._cards[key] = value

    deck = FranchDeck()

    print(deck[0])

    from random import choice

    print(choice(deck))

    print(choice(deck))

    from random import shuffle

    shuffle(deck)

    print(deck[:5])

    一道面试题

    class Person:

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

            self.name = name

            self.age = age

            self.sex = sex

        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

    p_lst = []for i in range(84):

        p_lst.append(Person('egon',i,'male'))print(p_lst)print(set(p_lst))

    相关文章

      网友评论

          本文标题:17、python面向对象进阶

          本文链接:https://www.haomeiwen.com/subject/euydoftx.html