Python 学习日记7

Posted aqqb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 学习日记7相关的知识,希望对你有一定的参考价值。

一,面向对象

  1.封装

# 广义上的封装 :把变量和函数都放在类中
# 狭义上的封装 :把一些变量 或者 方法 隐藏起来,不对外公开
    # 公有的 :
    # 私有的 : __名字

 静态属性、对象属性、方法(动态属性)前面加双下划线都会变成私有的

 私有的特点是只能在类的内部调用,不能在类的外部使用

 私有的变量:在类的内部使用,如果使用__变量的形式会发生变型,python会为你加上__类名

class Person:
    __country = 中国    # 私有静态属性

    def __init__(self,name,pwd):
        self.name = name
        self.__pwd = pwd      # 私有的对象属性

    def login(self):
        print(self.__dict__)
        if self.name == alex and self.__pwd == alex3714:
            print(登录成功)


alex = Person(alex,alex3714)
alex.login()
print(alex.__dict__)
私有的名字 只能在类的内部使用 不能在类的外部使用:AttributeError: type object ‘Person‘ has no attribute ‘__country‘
print(Person.__country)
2.反射
  通过字符串数据类型的变量名来访问变量的值
  x、y这样的形式,都可以反射
  
class Foo:
    country = "中国"
obj = Foo()
print(getattr(obj, "country"))

# 对象名 反射 对象属性 和 方法
class Foo:
    country = "中国"
    def __init__(self,name):
        self.name = name
    def func(self):
        print("%s in func" %self.name)
obj = Foo("spf")
getattr(obj, "func")()


# 模块 反射 模块中的名字
import sys
from  mypickle import MyPickle
choice = input(">>>:")
getattr(MyPickle, choice)(obj, "test.pkl")


# 反射 自己所在文件中的名字
from  mypickle import MyPickle
choice = input(">>>:")
ret = getattr(sys.modules[__name__], choice)
ret.dump(obj, "test.pkl")
print(ret.load("test.pkl"))

  4.类的内置方法

# __new__    构造方法 创建一个对象
# __init__   初始化方法

class Foo:
    def __new__(cls, *args, **kwargs):
        print(执行我啦)
        obj = object.__new__(cls)
        print(obj)
        return obj
    def __init__(self):
        print(1, self)

Foo()

  先执行new方法,object.new()

  再执行init

  Foo() --> python解释器接收到你的python代码

  python解释器替你去做了很多操作

  包括 主动帮助你 调用 new方法 去创造一个对象 —— 开辟内存空间 —— python语言封装了开辟内存的工作

  object的new方法里 —— 帮你创造了对象

  调用init用到的self参数 就是new帮你创造的对象

 

# 什么叫单例模式
# 单例模式 : 某一类 只有一个实例

class Person:
    __isinstance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__isinstance :
            obj = object.__new__(cls)
            cls.__isinstance = obj
        return cls.__isinstance
    def __init__(self,name):
        self.name = name

alex = Person(alex)
alex.age = 18
egon = Person(egon)
print(egon.age)
print(id(alex))
print(id(egon))
print(alex.name)
print(egon.name)

# __new__生孩子
# 类 : 生一个小孩__new__ 给这个小孩穿衣服 __init__
# 单例模式下的类 : 只有一个小孩

 

二、模块

  1、序列化

  定义:数据类型转化为字符串的过程

  特点:数据类型从内存到文件

  数据在网络上传播  字节 -- 字符串 -- 字典

  序列化模块都有哪些?

  josn  通用的,支持类型 list  touple  dict

  pickle  python中通用的,支持几乎所有的python中的数据类型

  

技术分享图片
# json
# dumps loads
# 内存读写
import json
dic = {"k": v}
json_dic = json.dumps(dic)   # 字典转字符串的过程 ——序列化
print(json_dic)
print(json.loads(json_dic))  # 字符串转回其他数据类型 —— 反序列化

# dump load
# 文件读写
dic = {"k": v}
with open(test.json, w) as f:
    json.dump(dic, f)
    # json.dump(dic, f)       # 在json中 dump默认不支持dump多条数据

with open(test.json) as f:
    print(json.load(f))      # 从文件中反序列化


# 如果要dump多条数据,每一条数据线dumps一下 编程字符串 然后打开文件 write写进文件里 \n
# 读取的时候按照标志读取或者按行读,读出来之后 再使用loads
with open(test.json, w) as f:
    str_dic = json.dumps(dic)
    f.write(str_dic+\n)
    f.write(str_dic+\n)
    f.write(str_dic+\n)
    f.write(str_dic+\n)

with open(test.json) as f:
    for line in f:
        print(json.loads(line.strip()))
josn
# pickle 和 json用法一致。但是pickle可以dump多条数据
# 1.pickle支持更多的数据类型
# 2.pickle的结果是二进制
# 3.pickle在和文件交互的时候可以被多次load
import pickle


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

alex = A(alex)
print(pickle.dumps(alex))
with open(test.pkl, wb) as f:
    pickle.dump(alex, f)
    pickle.dump(alex, f)     # 可以dump多条数据
    pickle.dump(alex, f)     # 可以dump多条数据

with open(test.pkl, rb) as f:
    while True:  # 通过循环取出所有的数据
        try:
            obj = pickle.load(f)
            print(obj.name)
        except EOFError:
            break

  2.logging

#!/usr/bin/env python3
# 函数式简单配置
import logging
logging.debug(debug message)
logging.info(info message)
logging.warning(warning message)
logging.error(error message)
logging.critical(critical message)

# 默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,
# 这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。

# 灵活配置日志级别,日志格式,输出位置:
import logging

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=./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用户输出的消息
"""


# logger对象配置
import logging

logger = logging.getLogger()    # 实例化一个logger对象

fh = logging.FileHandler(test1.log, encoding=utf-8)  # 创建一个文件handler,用于写入日志文件
ch = logging.StreamHandler()   # 再创建一个终端handler,用于输出到控制台

formatter_File = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s)  # 定义文件日志格式
formatter_Stream = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s)  # 定义终端日志格式

logger.setLevel(logging.DEBUG)  # 定义文件日志级别
logger.setLevel(logging.DEBUG)  # 定义终端日志级别

fh.setFormatter(formatter_File)      # 设置文件日志格式
ch.setFormatter(formatter_Stream)    # 设置终端日志格式

logger.addHandler(fh)  # logger对象可以添加多个fh和ch对象
logger.addHandler(ch)

logger.debug(logger debug message)
logger.info(logger info message)
logger.warning(logger warning message)
logger.error(logger error message)
logger.critical(logger critical message)

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


def my_logger(log_file):
    """
    定义日志输出合格
    :return: 返回一个可以直接使用的logger对象
    """
    import logging
    logger = logging.getLogger()    # 实例化一个logger对象
    fh = logging.FileHandler(log_file, encoding=utf-8)  # 创建一个文件handler,用于写入日志文件
    ch = logging.StreamHandler()                          # 创建一个终端handler,用于输出到控制台
    formatter = logging.Formatter(%(asctime)s  %(name)s   %(levelname)s  %(message)s File:<%(filename)s line %(lineno)d>)  # 定义文件日志格式
    logger.setLevel(logging.DEBUG)  # 定义文件日志级别
    fh.setFormatter(formatter)      # 设置文件日志格式
    ch.setFormatter(formatter)      # 设置终端日志格式
    logger.addHandler(fh)           # logger对象fh对象
    logger.addHandler(ch)           # logger对象ch对象
    return logger


log = my_logger("./test1.log")
log.debug(logger debug message)
log.info(logger info message)
log.warning(logger warning message)
log.error(logger error message)
log.critical(logger critical message)

 

 

 

 

 

































以上是关于Python 学习日记7的主要内容,如果未能解决你的问题,请参考以下文章

Python学习日记之练习代码

python开发学习日记01(字符串)

python日记----2017.7.27

Python学习日记——判断素数

python日记----2017.7.28

统计师的Python日记第九天:正则表达式