python 之 面向对象(三)

isinstance 和 issubclass

class Foo:
    pass
class Son(Foo):
    pass
s =Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
print(isinstance (s,Son))
print(isinstance (s,Foo))
print(type(s) is Son)#Ture
print(type(s) is Foo)#False 
#isinstance he type 的区别,type可以做精准判断

#判断一个类是不是另一个类的子类
print(issubclass(Son,Foo))
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))
python 中所有类的父类都是object

反射

什么是反射

反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

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

四个可以实现自省的函数

hasattr getattr setattr delattr

class Foo:
    def __init__(self):
        self.name = "egon"
        self.age = 73
    def func(self):
        print(123)
egg = Foo()
edd = Foo()
#常用的hasattr
#常用的getattr
# print(hasattr(egg,'name'))#True
# print(getattr(egg,'name'))#egon
#先通过hasattr判断里面有没有,再用getattr取出来
# if hasattr(egg,'func'):#如果存在返回属性值或者方法的内存地址,不存在报错
#     q = getattr(egg,'func')#这两种方法常一起结合使用
#     q()
#不常用
# setattr
# setattr(egg,'sex','male')
# print(egg.sex)
def show_name(self):
    print( self.name+"sb")
setattr(egg,'sh_name',show_name)

egg.sh_name(egg)
show_name(egg)
egg.sh_name#这里是需要传参数的

#delattr
#delattr(egg,'name')
#print(egg.name)
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,'www','没有'))#报错,这里的getattr有一个默认参数default可以赊着

#设置属性
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')
print(obj.__dict__)
# delattr(obj,'show_name111')#不存在会报错
class Foo(object):
    staticField = 'old boy'
    def __init__(self):
        self.name = "wupeiqi"
    def func(self):
        return 'func'
    @staticmethod
    def bar():
        return 'bar'
print(Foo.bar())
print(getattr(Foo,'staticField'))
print(getattr(Foo,'func'))
print(getattr(Foo,'bar'))

 

import sys
def s1():
    print('s1')
def s2():
    print('s2')
this_module = sys.modules[__name__]#查看当前模块

print(hasattr(this_module,'s1'))
print(getattr(this_module,'s2'))
反射当前模块成员

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

def test():
    print('from the test')
my_module.py
'''程序目录:
my_module.py
随笔.py
当前文件:
随笔.py'''
import my_module as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
随笔.py

内置方法

__str__ 和__repr__

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

自定制格式化字符串__format__

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

    def __str__(self):
        return 'School2(%s,%s)' % (self.name, self.addr)
    def __repr__(self):
        return 'School1(%s,%s)'%(self.name,self.addr)
    def __format__(self,format_spec):
        if not format_spec or format_spec not in format_dic:
            format_spec = 'tna'
        fmt = format_dic[format_spec]
        return fmt.format(obj =self)
s1 = School('oldboy1','北京','私立')
print('from %r'%s1)
print('from %s'%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"))
'''当打印一个对象的时候,如果实现了str,打印str中的返回值
当str没有被实现的时候,就会调用repr方法
但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
但反之不行
用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr
'''

__del__

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

执行del 方法时调用__del__

注:构析函数的调用是由解释器在进行垃圾回收自动触发执行的

class Foo:
    def __del__(self):
        print('执行我啦')

f = Foo()
print(123)
print(123)
try:#使用try处理一下
    del f
    print(f)#NameError: name 'f' is not defined
except NameError as e:
    print("name f 已经被删除了")
finally:
    print(123)

item系列

__getitem__       __setitem__     __delitem__

class Foo:
    def __init__(self):
        self.name = 'egon'
        self.age = 73
    def __getitem__(self, item):
        return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __delitem__(self, key):
        del self.__dict__[key]
f = Foo()
print(f['name'])#egon
f['name'] = 'alex'
print(f.name)#alex
del f['name']
print(f.name)#AttributeError: 'Foo' object has no attribute 'name'
f1 = Foo()
print(f == f1)#False
item系列

__new__

class A:
    def __init__(self):#调用init前先执行new方法
        print('in init function')
    def __new__(cls, *args, **kwargs):
        print('in new function')
        return object.__new__(A,*args,**kwargs)#new 方法必须有一个返回值
a = A()
b = A()
c = A()
d = A()

object 将__new__()定义为静态方法,并且至少需要传递一个cls,cls表示需要实例化的类,此参数在实例化时由python解释器自动提供。

实例化对象的时候,在调用__init__()方法之前,先调用了__new__()方法

__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回。

__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上才可以完成其它初始化动作,__init__()不需要返回值。

若__new__()没有正确返回当前类的cls实例,那__init__()将不会被调用,即使是父类的实例也不行。

 

单例模式

单例模式是一种常用的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例,单利对象就能派上用场。

class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'a'):
            cls.a = object.__new__(cls,*args,**kwargs)
        return cls.a
one = Singleton()
two = Singleton()
print(one,two)
print(one == two)#True  one 就是 two
# <__main__.Singleton object at 0x0128FBD0> <__main__.Singleton object at 0x0128FBD0>
one.name = "alex"
print(two.name)
单例模式

 __call__

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

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

# class Foo:
#     def __init__(self):
#         pass
#     def __call__(self, *args, **kwargs):
#         print('__call__')
# obj = Foo()#执行__init__
# obj()#__call__
class Storage(dict):
    # __call__方法用于实例自身的调用
    #达到()调用的效果
    def __call__ (self, key):
         try:
            return self[key]
         except KeyError as k:
             return None
s = Storage()
s['jjjk'] = 'aaaaa'#这里相当于添加了一个字典,调用key就会返回对应的value

print (s('jjjk') )#调用__call__  返回aaaaa

__len__

# class A:
#     def __init__(self):
#         self.a = 1
#         self.b = 2
#         self.c = 3
#     def __len__(self):
#         return self.__dict__
# a = A()
# print(a.__len__())#{'a': 1, 'b': 2, 'c': 3}
class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))# 3

 __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(a.__hash__())#相当于print(hash(a))

__eq__

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

    def __eq__(self, other):
        if self.a == other.a and self.b == other.b:
            return True#False(这里可以实现定制)
a = A()
b = A()

print(a == b)

 

posted on 2017-08-18 20:08  keepDoing  阅读(128)  评论(0编辑  收藏  举报

导航