python ==》 面向对象的反射,(isinstance and issubclass)

1.staticmethod:(静态方法)

静态方法:让类里的方法直接被类调用,就像正常的函数一样。

class Staticmethod_Demo():
    role = 'Aray'

    @staticmethod
    def func():
        print('当普通方法用')
Staticmethod_Demo.func()

输出结果:
当普通方法用

2.classmethod:(类方法)

类方法:默认参数为:cls  ,可以直接用类名调用,可以与类属性交互。

class Classmethod_Demo():
    role = 'Aray'

    @classmethod
    def func(cls):
        print(cls.role)
Classmethod_Demo.func()


输出结果:
Aray

共同点:

  1.都可以直接被类调用,不需要实例化

不同点:

  1,类方法必须有一个cls参数表示这这个类,静态方法不需要,不能直接被使用。

绑定方法: 普通方法   类方法

非绑定方法:  静态方法

目前为止学的方法有:

  普通方法:默认有一个self对象传进来,并且只能被对象调用

  类方法:默认有一个cls传进来表示本类,并且可以被类和对象调用

  静态方法:没有默认参数,并且可以被类和对象调用。(这个方法不推荐使用)

3.isinstance

isinstance 作用是: 判断一个对象是不是这个类的对象,传两个参数,分别是对象和类,如果是,返回true,否则,为false。

class Foo:
    pass
class Son(Foo):
    pass
s = Son()  #实例化
print(isinstance(s,Son)) #判断一个对象是不是这个类的对象,传两个参数,分别是 对象和类
print(isinstance(s,Foo))
print(type(s) == Son)   #精准判断
print(type(s) == Foo)

输出结果:
True
True
True
False

4.issubclass

issubclass: 判断一个类是不是另一个类的子类,传两个参数,分别是子类和父类

class Foo:
    pass
class Son(Foo):
    pass
s = Son()  #实例化

print(issubclass(Son,Foo))  #判断一个类是不是另一个类的子类,传两个参数,分别是子类和父类
print(issubclass(Son,object))
print(issubclass(Son,Son))
print(issubclass(Foo,object))
print(issubclass(Foo,Son))

输出结果:
True
True
True
True
False

5.logging模块

logging的作用:1.不需要逐行注释      2.规范格式

设置方式:

  1.config

  2.logger对象

日志的级别等级: dubug,info,warning,error,critical

logging:实操练习

import logging
logging.basicConfig(
    level = logging.DEBUG,      #设置级别为debug
    format = '%(name)s %(asctime)s [%(lineno)d]--%(message)s',
    datafmt = '%Y-%m-%d %H-%M%S‘,
)
logging,debug('debug')   
logging.info('info)
logging.warning('出错了!')

#debug和info 是默认不会打印,等级太低,
#这里因为上面降低了级别,所以结果才能显示出来。


输出结果:
root 2017-08-18 16-34-24 [34]-- debug       
root 2017-08-18 16-34-24 [35]-- info 
root 2017-08-18 16-34-24 [36]-- 出错了
logging(1)

输出结果:

root 2017-08-18 17-01-40 [52]-- 出错了   

注意:
执行之后,会生成一个logging 文件,里面会又记载。(即又在屏幕输出,又在文件里生成)

logger对象:解决即在屏幕输出,又在文件里生成,像上面一种仅能在屏幕输出打印,而不能在文件里生成。

import logging
def my_logger():
    logger = logging.getLogger()  
    file_handler = logging.FileHandler('logging',ending = 'utf-8')
    stream_handler = logging.StreamHandler()
    formatter = logging.Formatter(fmt = '%(name)s %(asctime) [%(lineno)d]--%(message)s' , datefmt = '%Y-%m-%d- %H-%M-%S')  #设置输出格式,可有可无
    file_handler.setFormatter(formatter)  #文件流
    stream_handler.setFormatter(formatter)  #屏幕流
    logger.addHandler(file_handler)
    logger.addHandler(stram_handler)
    return logger
logger = my_logger()
logger.warning('出错了')
logger(2)

2.logger对象,可以限制是就屏幕输出,还是在文件里生成。 logger可以灵活的运用。

import  logging
def my_logger(filename,file = True, stream =True):
    logger = logging.getLogger()
    formatter = logging.Formatter(fmt = '%(name)s %(asctime)s [%(lineno)d]-- %(message)s',datefmt='%Y-%m-%d %H-%M-%S')
    logger.setLevel(logging.DEBUG)  #指定日志打印的等级
    if file:
        file_handler = logging.FileHandler('logging',encoding='utf-8')
        file_handler.setFormatter(formatter)  #文件流
        logger.addHandler(file_handler)

    if stream:
        stream_handler=logging.StreamHandler()
        stream_handler.setFormatter(formatter)  #屏幕流
        logger.addHandler(stream_handler)
    return logger

logger = my_logger('logging',file = False)   #限制在文件里生成。只在屏幕输出。
logger.warning('出错了')
logger.debug('debug')
View Code

输出结果:

root 2017-08-18 17-04-00 [72]-- 出错了
root 2017-08-18 17-04-00 [73]-- debug

注意:
这里是切到文件 logging 里 是没有记载的。因为给 False  了。

二:反射

反射:要求掌握 (多用在网络相关方面)。定义:可以用字符串的方式去访问对象的属性,调用对象的方法。

常用:

  hasattr:

  getattr:

hasattr和getattr通常是一起用的。一个检测,一个获取。

class Black_one:
    feature = 'ugly'
    def __init__(self,name,addr):
        self.name = name
        self.affr = addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不是傻逼呢?'%self.name)
    def rent_house(self):
        print('%s 黑中介介绍租房子啦,傻逼才租啊'%self.name)

b1 = Black_one('天地三清','道法无常')
#检测是否含有属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))

#获取属性
n = getattr(b1,'name')
print(n)
func = getattr(b1,'sell_house')
func()
print(getattr(b1,'aaaa','不存在'))


输出结果:
True
True
天地三清
天地三清 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不是傻逼呢?
不存在

不常用:

  setattr:

#设置属性(新增)
print(b1.__dict__)
setattr(b1,'SB',True)
setattr(b1,'time','1年')
print(b1.__dict__)

输出结果:{'name': '天地三清', 'addr': '道法无常'}
{'name': '天地三清', 'addr': '道法无常', 'SB': True, 'time': '1年'}

  delattr:

delattr(b1,'addr')
delattr(b1,'time')
print(b1.__dict__)

输出结果:
{'name': '天地三清', 'addr': '道法无常', 'SB': True, 'time': '1年'}
{'name': '天地三清', 'SB': True}

内置方法:

str and repr

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

    def __str__(self):
        return '%s obj info in str'%self.name

    def __repr__(self):
        return 'obj info in repr'

f = Foo('egon')
print(f)
print('%s'%f)
print('%r'%f)

输出结果:
egon obj info in str
egon obj info in str
obj info in repr

-del-:  如果没有手动删除,系统默认最后会del。

class Foo:
    def __del__(self):
        print('执行我啊!')
f = Foo()
print(123)
print(123)
print(123)
del f
print(123)
print(123)
print(123)


输出结果:
123
123
123
执行我啊!
123
123
123

item 系列:

class Foo:
    def __init__(self):
        self.l = [1,2,3]

    def __getitem__(self, item):
        return self.l[item]

f = Foo()
print(f[0])
print(f[1])
print(f[2])

输出结果:
1
2
3
class Foo:
    def __init__(self,name):
        self.name = 'aray'
        self.age = 12
        self.name = name             #这里对应的是下边的实例化所传的值,这个覆盖了上面的‘aray’。
    def __getitem__(self, item):
        return self.__dict__[item]
f = Foo('zbk')
print(f.__dict__)

输出结果:
{'name': 'zbk', 'age': 12}
class Foo:
    def __init__(self,name):
        self.name = 'aray'
        self.age = 12
        self.name = name
    def __setitem__(self, key, value):   #设置值
        self.__dict__[key] = value

f = Foo('zbk')
f['name'] = 'alex'
f['age'] = 12
print(f.__dict__)

输出结果:
{'name': 'alex', 'age': 12}
class Foo:
    def __init__(self,name):
        self.name = 'aray'
        self.age = 12
        self.name = name
    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):     #删除的方法
        self.__dict__.pop(key)

f = Foo('zbk')
f['name'] = 'alex'
f['age'] = 12
print(f.__dict__)
del f['age']
print(f.__dict__)

输出结果:
{'name': 'alex', 'age': 12}
{'name': 'alex'}

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

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

  

原文地址:https://www.cnblogs.com/zhongbokun/p/7374951.html