1. 程式人生 > >Python 學習日記7

Python 學習日記7

屬性 文件讀寫 情況 module 下劃線 json play error: pre

一,面向對象

  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