Python21期 day7 补充

一、常用模块

hashlib模块

算法介绍:Python的hashlib提供了常见的摘要算法,如MD5,SHA1等

摘要算法又称哈希算法、散列算法。通过一个函数,把任意长度的数据转换为一个固定的数据串(通常用16进制的字符串表示)

import hashlib

md5_obj = hashlib.md5()
md5_obj.update('hello world')
print(md5_obj.hexdigest())

如果数据量很大,可以分块多次调用update(),最后计算结果一样

不过使用摘要算法加密数据很容易被撞库,此时应该使用加盐处理,加盐就是在初始化md5对象时,添加一个复杂字符串的过程

第一种:加盐

md5_obj = hashlib.md5('alex'.encode('utf-8'))
md5_obj.update('123456')
md5_obj.hexdigest()


第二种:动态加盐
可以将输入的用户名作为加盐

username = input('name:').strip()
md5_obj = hashlib.md5(username.encode('utf-8'))
md5_obj.update('123456')
md5_obj.hexdigest()

configparse模块

该模块适用于配置文件的格式,与windows ini文件类似,可以包含一个或多个节(section),每个节可以由多个参数(键=值)

创建文件

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
  
[bitbucket.org]
User = hg
  
[topsecret.server.com]
Port = 50022
ForwardX11 = no

如果想用python生成一个这样的文档怎么做呢?

import configparser

config = configparser.ConfigParser()

config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9',
                     'ForwardX11':'yes'
                     }

config['bitbucket.org'] = {'User':'hg'}

config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'}

with open('example.ini', 'w') as configfile:

   config.write(configfile)

查找文件

import configparser

config = configparser.ConfigParser()

#---------------------------查找文件内容,基于字典的形式

print(config.sections())        #  []

config.read('example.ini')

print(config.sections())        #   ['bitbucket.org', 'topsecret.server.com']

print('bytebong.com' in config) # False
print('bitbucket.org' in config) # True


print(config['bitbucket.org']["user"])  # hg

print(config['DEFAULT']['Compression']) #yes

print(config['topsecret.server.com']['ForwardX11'])  #no


print(config['bitbucket.org'])          #<Section: bitbucket.org>

for key in config['bitbucket.org']:     # 注意,有default会默认default的键
    print(key)

print(config.options('bitbucket.org'))  # 同for循环,找到'bitbucket.org'下所有键

print(config.items('bitbucket.org'))    #找到'bitbucket.org'下所有键值对

print(config.get('bitbucket.org','compression')) # yes       get方法Section下的key对应的value

增删改操作

import configparser

config = configparser.ConfigParser()

config.read('example.ini')

config.add_section('yuan')



config.remove_section('bitbucket.org')
config.remove_option('topsecret.server.com',"forwardx11")


config.set('topsecret.server.com','k1','11111')
config.set('yuan','k2','22222')

config.write(open('new2.ini', "w"))

logging模块

函数式简单配置

import logging

logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

配置日志级别,日志格式,输出位置:

logging.basicConfig(level=logging.DEBUG,  
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                    datefmt='%a, %d %b %Y %H:%M:%S',  
                    filename='/tmp/test.log',  
                    filemode='w')  

logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')

配置参数:

logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
View Code

 

logging模块在输出日志时,无法输出多条日志,此时应使用logger对象

logger = logging.getLogger()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#输出日志到文件
fh = logging.FileHandler('py.log',encoding='utf-8')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.setLevel(logging.ERROR)

#输出到屏幕
sh = logging.StreamHandler()
sh.setFormatter(formatter)
logger.addHandler(sh)
logger.setLevel(logging.ERROR)

logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('程序出错了!!')
logging.critical('critical message')

logging库提供了多个组件:logger、Handler、Fiter、Formatter

Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过

fh.setLevel(logging.Debug)单对文件流设置某个级别。

 

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中的一切事物皆对象(都可以使用反射)

通常类似x.y 这样的形式,都可以使用反射

使用方法:

类名反射静态属性

对象名反射对象属性和方法

模块反射模块中的名字

反射自己所在文件中的名字

print('aaa'.startswith)
print('aaa'.startswith('a'))

ret = getattr('aaa','startswith')
print(ret)
print(ret('a'))
#结果 #<built-in method startswith of str object at 0x000000000210C1B8> #True #<built-in method startswith of str object at 0x000000000210C1B8>
#True

getattr 获取一个名字,如果在这个对象的命名空间没有这个名字,会报错

getattr反射的好伴侣hasattr,常用于组合

如果使用getattr 去获取一个方法,只能拿到这个方法的内存地址,加上()就是执行

如果getattr 获取一个属性,直接使用反射获取值就可以获取到值

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'))    #True
print(hasattr(obj,'say_hi'))   #True


#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()


#设置属性
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'))
print(getattr(Foo, 'bar'))
import sys

def s1():
    print('s1')
def s2():
    print('s2')

this_module = sys.modules[__name__]
# print(this_module)
print(hasattr(this_module,'s1'))
print(getattr(this_module,'s2'))

__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)
class Single:
    __instance = None

    def __new__(cls,*args,**kwargs):
        if not cls.__instance:
            obj = object.__new__(cls)
            cls.__instance = obj
        return cls.__instance

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

alex = Single('alex')
egon = Single('egon')
print(alex.name)
print(egon.name)


#结果
#egon
#egon
单例模式

 

posted @ 2018-05-30 15:25  叫你你敢答应么  阅读(110)  评论(0)    收藏  举报