查看: 161|回复: 0

Python—面向对象进阶

[复制链接]
发表于 2020-2-16 03:56:48 | 显示全部楼层 |阅读模式
isinstance和issubclass

isinstance(obj,cls)查抄是否obj是否是类 cls 的对象
  1. class Foo(object):     pass  obj = Foo()  isinstance(obj, Foo)
复制代码
issubclass(sub, super)查抄sub类是否是 super 类的派生类
  1. class Foo(object):    pass class Bar(Foo):    pass issubclass(Bar, Foo)
复制代码
反射

1 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指步伐可以访问、检测和修改它本身状态或活动的一种能力(自省)。这一概念的提出很快引发了计算机科学范畴关于应用反射性的研究。它首先被步伐语言的计划范畴所采用,并在Lisp和面向对象方面取得了成绩。
2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的统统事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(统统皆对象,类本身也是一个对象)

  1. 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
  1. 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
  1. 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
  1. 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
  1. 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__)
复制代码
四个方法的使用演示
  1. 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')print getattr(Foo, 'bar')
复制代码
类也是对象
  1. #!/usr/bin/env python# -*- coding:utf-8 -*-import sysdef s1():    print 's1'def s2():    print 's2'this_module = sys.modules[__name__]hasattr(this_module, 's1')getattr(this_module, 's2')
复制代码
反射当前模块成员导入其他模块,利用反射查找该模块是否存在某个方法

  1. #!/usr/bin/env python# -*- coding:utf-8 -*-def test():    print('from the test')
复制代码
View Code
  1. #!/usr/bin/env python# -*- coding:utf-8 -*- """步伐目次:    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__
  1. #_*_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'))
复制代码
View Code
  1. class B:     def __str__(self):         return 'str : class B'     def __repr__(self):         return 'repr : class B'b=B()print('%s'%b)print('%r'%b)
复制代码
%s和%ritem系列

__getitem__\__setitem__\__delitem__
  1. 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']=18f1['age1']=19del f1.age1del f1['age']f1['name']='alex'print(f1.__dict__)
复制代码
View Code__del__

析构方法,当对象在内存中被释放时,主动触发执行。
注:此方法一般无须定义,由于Python是一门高级语言,步伐员在使用时无需关心内存的分配和释放,由于此工作都是交给Python表明器来执行,所以,析构函数的调用是由表明器在进行垃圾回收时主动触发执行的。
  1. class Foo:    def __del__(self):        print('执行我啦')f1=Foo()del f1print('------->')#输出结果执行我啦------->
复制代码
简朴树模__new__

  1. 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)a = A()print(a.x)
复制代码
View Code
  1. class Singleton:    def __new__(cls, *args, **kw):        if not hasattr(cls, '_instance'):            cls._instance = object.__new__(cls)        return cls._instanceone = 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__ 方法的执行是由对象后加括号触发的,即:对象() 大概 类()()
  1. class Foo:    def __init__(self):        pass        def __call__(self, *args, **kwargs):        print('__call__')obj = Foo() # 执行 __init__obj()       # 执行 __call__
复制代码
with和__enter__,__exit__

  1. class A:    def __enter__(self):        print('before')    def __exit__(self, exc_type, exc_val, exc_tb):        print('after')with A() as a:    print('123')
复制代码
with语句
  1. class A:    def __init__(self):        print('init')            def __enter__(self):        print('before')    def __exit__(self, exc_type, exc_val, exc_tb):        print('after')with A() as a:    print('123')
复制代码
with语句和init
  1. class Myfile:    def __init__(self,path,mode='r',encoding = 'utf-8'):        self.path = path        self.mode = mode        self.encoding = encoding    def __enter__(self):        self.f = open(self.path, mode=self.mode, encoding=self.encoding)        return self.f    def __exit__(self, exc_type, exc_val, exc_tb):        self.f.close()with Myfile('file',mode='w') as f:    f.write('wahaha')
复制代码
with和文件操作
  1. import  pickleclass MyPickledump:    def __init__(self,path):        self.path = path    def __enter__(self):        self.f = open(self.path, mode='ab')        return self    def dump(self,content):        pickle.dump(content,self.f)    def __exit__(self, exc_type, exc_val, exc_tb):        self.f.close()class Mypickleload:    def __init__(self,path):        self.path = path    def __enter__(self):        self.f = open(self.path, mode='rb')        return self    def __exit__(self, exc_type, exc_val, exc_tb):        self.f.close()    def load(self):         return pickle.load(self.f)    def loaditer(self):        while True:            try:                yield  self.load()            except EOFError:                break# with MyPickledump('file') as f:#      f.dump({1,2,3,4})with Mypickleload('file') as f:    for item in f.loaditer():        print(item)
复制代码
with和pickle
  1. import  pickleclass MyPickledump:    def __init__(self,path):        self.path = path    def __enter__(self):        self.f = open(self.path, mode='ab')        return self    def dump(self,content):        pickle.dump(content,self.f)    def __exit__(self, exc_type, exc_val, exc_tb):        self.f.close()class Mypickleload:    def __init__(self,path):        self.path = path    def __enter__(self):        self.f = open(self.path, mode='rb')        return self    def __exit__(self, exc_type, exc_val, exc_tb):        self.f.close()    def __iter__(self):        while True:            try:                yield  pickle.load(self.f)            except EOFError:                break# with MyPickledump('file') as f:#      f.dump({1,2,3,4})with Mypickleload('file') as f:    for item in f:        print(item)
复制代码
with和pickle和iter__len__

  1. class A:    def __init__(self):        self.a = 1        self.b = 2    def __len__(self):        return len(self.__dict__)a = A()print(len(a))
复制代码
View Code__hash__

  1. 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))
复制代码
View Code__eq__

  1. 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 Truea = A()b = A()print(a == b)
复制代码
View Code
  1. 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))
复制代码
纸牌游戏1
  1. 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] = valuedeck = FranchDeck()print(deck[0])from random import choiceprint(choice(deck))print(choice(deck))from random import shuffleshuffle(deck)print(deck[:5])
复制代码
纸牌游戏2
  1. 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 Truep_lst = []for i in range(84):    p_lst.append(Person('egon',i,'male'))print(p_lst)print(set(p_lst))
复制代码
一道面试题

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?用户注册

x

天涯海角也要找到Ni:Python—面向对象进阶

相关技术服务需求,请联系管理员和客服QQ:2753533861或QQ:619920289
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

帖子推荐:
客服咨询

QQ:2753533861

服务时间 9:00-22:00

快速回复 返回顶部 返回列表