python之路----面向对象进阶一

一、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)

 二、反射

 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
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
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
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 A:
    def func(self):
        print('in func')

a = A()
a.name = 'alex'
a.age = 63
ret = getattr(a,'name')  # 通过变量名的字符串形式取到的值
print(ret)
print(a.__dict__)
变量名 = input('>>>')   # func
print(getattr(a,变量名))
print(a.__dict__[变量名])
反射对象的属性
a.func()
ret = getattr(a,'func')
ret()
反射对象的方法

2.反射类中的属性和方法

class A:
    price = 20
    @classmethod
    def func(cls):
        print('in func')
# A.price
print(getattr(A,'price'))
# 反射类的属性

# A.func()
if hasattr(A,'func'):
    getattr(A,'func')()
反射类的方法

3.反射模块中的属性和方法

import my
反射模块的属性
print(my.day)
print(getattr(my,'day'))

反射模块的方法
getattr(my,'wahaha')()

4.内置模块的反射

time
asctime
import time
print(getattr(time,'time')())
print(getattr(time,'asctime')())

5.反射自己模块中的变量和函数

def qqxing():
    print('qqxing')
year = 2018
import sys
print(sys.modules['__main__'].year)
反射自己模块中的变量
print(getattr(sys.modules['__main__'],'year'))

反射自己模块中的函数
getattr(sys.modules['__main__'],'qqxing')()

6.要反射的函数有参数怎么办?

# print(time.strftime('%Y-%m-%d %H:%M:S'))
# print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))

7.setattr  设置修改变量

setattr  设置修改变量
class A:
    pass
a = A()
setattr(a,'name','nezha')
setattr(A,'name','alex')
print(A.name)
print(a.name)
setattr 设置修改变量

8. delattr 删除一个变量

# delattr 删除一个变量
delattr(a,'name')
print(a.name)
delattr(A,'name')
print(a.name)
# delattr 删除一个变量

9四个方法的使用演示

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

四个方法的使用演示
四个方法的使用演示

三、内置的类方法 :和内置的函数之间有着千丝万缕的联系

 __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'))
View Code
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和%r
View Code

__del__

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

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

class Foo:

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

f1=Foo()
del f1
print('------->')

#输出结果
执行我啦
------->

 简单示范
简单示范

 

 

posted @ 2018-01-22 16:22  TheLand  阅读(173)  评论(0编辑  收藏  举报