7)封裝、反射、序列化以及logging 、configparse 、 hashilib模塊

、封裝使用

 

 

封裝:

 

#封裝 變量和函數都放在類中,廣義
#狹義的封裝:吧一些變量或者方法隱藏起來,不對外公開,只提供內部使用
 #共有的
 #私有的:__名字

 

 

 

class Person:
    __country = '中國'

# print(Person.__country)#AttributeError: type object 'Person' has no attribute '__country'
#私有屬性,只能在類的內部使用,不能在類的外部使用
print(Person.__dict__)# '_Person__country'
#_Person__country
print(Person._Person__country)#中國
#如果非要在類的外部調用一個私有的名字,name必須是在私有的名字前加_類名__私有的名字
#不能使用上面這種方式去調用私有的變量

 

 圖片1.png

#私有的變量:

在類的內部如果使用__變量的形式會發生變形,python會自動加上_類名

class Person:
    __country = '中國'

# print(Person.__country)#AttributeError: type object 'Person' has no attribute '__country'
#私有屬性,只能在類的內部使用,不能在類的外部使用
# print(Person.__dict__)# '_Person__country'
# #_Person__country
# print(Person._Person__country)#中國
#如果非要在類的外部調用一個私有的名字,name必須是在私有的名字前加_類名__私有的名字
#不能使用上面這種方式去調用私有的變量

 


Person.__name = 'XXX'
print(Person.__name) #在類的外部不能定義一個私有的變量
print(Person.__dict__)

 

 圖片2.png

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('ok')
alex = Person('alex','alex3714')
alex.login()
print(alex.__dict__)

 

內部方法:

class Person:
    def __init__(self):pass
    def __eat(self):
        print('thins is eating')
alex = Person()
alex.__eat()

 

#靜態屬性、對象屬性、方法(動態屬性)前面加上雙下劃線會變成私有的

#私有的特定就是只能在類的內部調用,不能再類的外部使用

 

二、類中的裝飾器方法

classmethod staticmethod  property
#三個裝飾器函數

 

from  math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def area(self):
        return self.r **2 * pi
    @property
    def perimeter(self):
        return self.r *2 * pi

#將一個函數僞裝成一個屬性@property

c = Circle(3)
print(c.area)
print(c.perimeter)

 

驗證一個蘋果價格折扣例子:

class Goods:
    def __init__(self,price,discount):
        self.__price = price
        self.discount = discount
    @property
    def price(self):
        return self.__price * self.discount
    @price.setter
    def price(self,newprice):
        self.__price = newprice

    @price.deleter
    def price(self):
        del self.__price
apple = Goods(8,0.7)
print(apple.price)
apple.price = 10
del apple.price
print(apple.__dict__)
print(apple.price)

Calssmethod模塊

class Person:
    country = '中國人'
    @classmethod
    def func(cls):
        print('當前角色國籍%s'%cls.country)
Person.func()


#如果某一個類中的方法,並沒有用到這個類的實例中的具體屬性
#只是用到了類中的靜態變量,就是用類方法

 

 

staticmethod 模塊
class Student:
    @staticmethod
    def login():
        name = input(">>name")
        pwd = input(">>pwd")
        if name ==' ' and pwd ==' ':
            print('實例化')
Student.login()

 

序列化模塊:

#什麼交序列化呢?
#{'11111:{'name:'xx,'age:24}}
    #數據類型---字符串的過程
#爲什麼要用序列化
    #數據從內存到文件
        #數據在網絡上傳輸  字節--字符串 - 字典
#python序列化模塊有哪些
 #json   通用的,支持的數據類型也少   list  tuple  dict
 #pickle    python中通用的 支持幾乎所有的數據類型
 #shelve     python中使用的邊界的序列話工具
 
 
 # dumps  loads
 #dump   load


圖片3.png圖片4.png

 

多次寫讀數據

 圖片5.png


 

Pickle

 

 

 

圖片9.png

圖片10.png

兩個必須會:

#登陸
#數據庫
#存儲用戶密碼的時候: 不適用明文
#對用戶密碼進行計算,得到一個新的固定的字符串
#hashlib模塊  摘要算法
#包含了多種算法
#將一個字符串進行摘要運算 拿到一個固定的值
import hashlib
hashlib.md5()
#能夠讓一個字符串唯一的對應一個固定的值
#sha/md5()

 

圖片11.png 

Md5算法

import hashlib
md5obj = hashlib.md5() #實例化一個md5的摘要算法的對象
md5obj.update('alex3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串
ret = md5obj.hexdigest() #hex+digest  16進制+消化
print(ret,type(ret),len(ret))

 

1Sha算法

import hashlib

md5obj = hashlib.sha512() #實例化一個md5的摘要算法的對象
md5obj.update('alex3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串
ret = md5obj.hexdigest() #hex+digest  16進制+消化
print(ret,type(ret),len(ret))

 

 

#撞庫
#Md5
#加鹽
import hashlib
md5obj = hashlib.md5() #實例化一個md5的摘要算法的對象
md5obj.update('alex3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串
ret = md5obj.hexdigest() #hex+digest  16進制+消化
print(ret,type(ret),len(ret))

 

2、#撞庫
#Md5
#加鹽
md5obj = hashlib.md5('tesla'.encode('utf-8')) #實例化一個md5的摘要算法的對象
md5obj.update('alex3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串
ret = md5obj.hexdigest() #hex+digest  16進制+消化
print(ret,type(ret),len(ret))

 

 

3、#動態加鹽
username = 'alex' #用戶加鹽
md5obj = hashlib.md5(username.encode('utf-8')) #實例化一個md5的摘要算法的對象
md5obj.update('alex3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串
ret = md5obj.hexdigest() #hex+digest  16進制+消化
print(ret,type(ret),len(ret))

 

拆分讀字節,防止太大5G

 

md5obj = hashlib.md5() #實例化一個md5的摘要算法的對象
md5obj.update('alex'.encode('utf-8'))#使用md5算法的對象來操作一個字符串# 等同於alex3714
md5obj.update('3714'.encode('utf-8'))#使用md5算法的對象來操作一個字符串#等同於alex3714
print(md5obj.hexdigest())

 

Configparse模塊:

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 f:
   config.write(f)

 

 

 

import logging
#日誌
#程序出錯---日誌對內看的
#對外給用戶看的

#簡單配置
logging.basicConfig(level=logging.DEBUG)
logging.debug('debug message')  #非常細節的日誌---排查錯誤
logging.info('info message')   #正常的日誌信息
logging.warning('warning message')#小問題可以運行 警告
logging.error('error message')  #錯誤
logging.critical('critical message')#嚴重錯誤

 


#logger對象的方式配置

import logging
logger = logging.getLogger()
# 吸星大法
#創造一個格式
format=logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
format1=logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')

#文件裏輸入
fh = logging.FileHandler('LOG.log') #創造了一個操作文件的對象fh
fh.setFormatter(format)
logger.addHandler(fh)

#往屏幕上寫
sh = logging.StreamHandler()
sh.setFormatter(format1)
logger.addHandler(sh)
#內容
logger.warning('www message')

 





圖片12.png

 

#反射
#通過字符串數據類型的變量名 來訪問變量的值

name = 'value'
#類名 反射 靜態屬性 和方法
#模塊 反射模塊中的名字
#反射 自己搜在文件中的名字
#xx.yy這種形式 都可以用反射


#'startswith'
print('aaa'.startswith('a'))
ret = getattr('aaa','startswith')
print(ret('a'))

 

 

有點問題

:

class Person:
    role = 'Person'
    def __init__(self,name):
        self.name = name
    def eat(self):print('eating')
    def drink(self):print('drinking')
    def play(self):print('playing')
    def sleep(self):print('sleepping')

alex = Person('alex')
alex.name
print(getattr(alex,'name'))
print(getattr(Person,'role'))

 


while True:
    inp = input('>>>')
    if hasattr(alex,inp):
        getattr(alex,inp)()


#首先使用getattr獲取一個名字,如果在這個對象的命名空間中沒有這個名字 會報錯
#getattr的反射好伴侶 hasattr
#如果使用getattr獲取一個方法,那麼只能拿到一個方法的內存地址
#如果getattr獲取一個屬性,那麼直接使用反射就可以獲取到值

 

 

#__new__    構造方法  創建一個對象
#__init__  初始化方法

class Foo:
    def __new__(cls, *args, **kwargs):
        print('執行我了')
        return object.__new__(cls)
    def __init__(self):
        print('22222222')

Foo()
#先執行new方法,objectf.new()
#在執行init

 

 

#單列模式
class Persion:
    __isinstace = None
    def __new__(cls, *args, **kwargs):
        if not cls.__isinstace:
            obj = object.__new__(cls)
            cls.__isinstace = obj
        return cls.__isinstace
    def __init__(self,name):
        self.name = name

alex = Persion('alex')
egon = Persion('egon')
print(id(alex))
print(id(egon))

 

 

 

圖片13.png 

 

#__new__ 生小孩
#類: 生一個小孩__new__ 給小孩穿衣服__init__

#單類模式下的類: 只有一個小孩

 

 

#len 方法
class A:
    def __len__(self):
        return 10

print(len([1,2,3]))
a = A()
print(len(a))
#類中的內置方法 很多都和 內置函數相關

 


class Person:
    def __init__(self,name):
        self.name = name
    def __str__(self):
        return 'a object of Person named %s'%self.name
    # def __hash__(self):
    #     return 1231212
    # def __len__(self):
    #     return 10
a = Person('alex')
b = Person('egon')
# print(len(a))
# print(hash(a))
print(a)
print(b)

 

 圖片14.png

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章