1.模塊python
2.包併發
3.isinstance issubclass typeapp
4.方法和函數函數
5.反射高併發
6.約束測試
7.繼承this
8.特殊成員spa
9.異常處理debug
補充知識點日誌
10.hashlib模塊
11.logging日誌模塊
模塊的概述:模塊本質上就是一個py文件,一行一行代碼多了會經過函數來封裝,函數多了之後會經過class類來封裝,class類多了就經過一個個py文件,也就是咱們
所說的模塊。導入模塊的方式:import py文件 或者 from py文件 import py文件裏面的具體xxx
導入模塊的工做原理:
1.判斷內存中是否有master ps:以master文件爲例
2.若是有,直接拿過來使用
3.若是沒有,會開闢一個內存空間
4.在該內存空間中執行模塊中的代碼
5. 默認把名稱空間的名字引入進來
導入模塊的規則:
規則
1.導入模塊寫入py文件的最開始
2.順序
內置模塊》第三方模塊》本身定義的模塊
__name__ 在當前文件做爲啓動文件的時候"__main__"
當py文件做爲模塊被導入的時候是文件本身的名字
python程序的模塊搜索路徑 經過sys.path查看
sys.modules 當前已經導入的模塊
sys.path 模塊的搜索路徑
sys.path.append ps:可添加xx路徑到path路徑下
包的概述: 包下面存放的是一個個py文件,好處:結構清晰易於管理
包的導入方式:from 路徑 import 包 ps: import 不能直接加點, 點在這裏表明的是xx下的xx。import 後直接寫目錄默認會導入__init__.py文件。導入包的path以包的啓動文件爲準。導入包有 兩種方式相對導入和絕對導入,相對導入容易出問題,相對導入在導入的那個文件裏面執行代碼會報錯,緣由是不能出當前path文件,因此通常推薦絕對導入。
isinstance:查看某數據的類型
insubclass:查看xx 是不是xx的子類
type: 查看數據的具體類型
class Animal:
def run(self):
print("動物會跑")
class dog(Animal):
def play(self):
print("dog can run")
cat = Animal()
print(type(cat))
print(isinstance(cat,Animal))
print(issubclass(dog,Animal))
<class '__main__.Animal'>
True
True
type的應用小場景
def Sum(a,b):
"""
:param a:
:param b:
:return:
"""
if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
return a + b
else:
print("輸入類型錯誤")
ret = Sum(9.99,9)
print(ret) ps:在python裏面三個雙引號而後回車是文本註釋,能夠對你的代碼進行闡述。
首先理解建立對象的概念,經過類來建立對象的時候,會生成一個兌現的命名空間而後把類的init方法下的屬性都拿過來,再把類下面的方法名寫到對象的命名空間裏面,此時對於對象下的方法名就是一個綁定方法,當執行對象.方法的時候,實際上仍是執行類下面的方法,在這裏就能體現出綁定方法了。但對於類來講若是經過類名.方法調用。本質上仍是一個函數。所以能夠得出一個結論 對象.方法 = 方法 類.方法 = 函數 (實例方法)類方法classmethod 類.方法 = 方法 對象.方法 = 方法 (類方法和類屬性通常都是比較推薦經過類調用) 最後一種是靜態方法: staticclass 無論經過什麼方式來調用始終都是函數。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def eat(cls):
print("this is a class method")
@staticmethod
def drink():
print("this is a staic method")
def sleep(self):
print("this is a instance method")
p = Person("jack",19)
print(p.eat)
print(Person.eat)
print(Person.sleep)
print(p.drink)
print(p.sleep)
<bound method Person.eat of <class '__main__.Person'>>
<bound method Person.eat of <class '__main__.Person'>>
<function Person.sleep at 0x0000013C3CD5E510>
<function Person.drink at 0x0000013C3CD5E488>
<bound method Person.sleep of <__main__.Person object at 0x0000013C3CD6A128>>
判斷是方法仍是函數
from types import FunctionType,MethodType
print(isinstance(p.sleep,FunctionType))
print(isinstance(p.sleep,MethodType))
print(isinstance(p.eat,FunctionType))
print(isinstance(p.eat,MethodType))
print(isinstance(p.drink,FunctionType))
print(isinstance(p.drink,MethodType))
反射只用四個方法,經常使用的就hasattr和getattr
hasattr(obj,str)判斷對象裏面是否有xx屬性
getattr(obj,str) 獲取obj裏面的str屬性
delattr(obj,str)刪除obj裏面的str屬性
setattr(obj, str,xx) 給obj設置str屬性
import daniu
while 1:
skill = input("請輸入你要測試的功能: ")
if hasattr(daniu,skill):
new_skill = getattr(daniu,skill)
if callable(new_skill):
new_skill()
else:
print(f"{new_skill}不能被調用")
else:
print("尚未這個功能")
代碼解讀:導入daniu模塊,判斷daniu裏面是否有skill屬性,若是有獲取而後在判斷是否可調用,若是可調用就執行不然直接打印不可調用。
刪除屬性的例子:
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def haha(self):
print("haha")
p = Person("ivy","18")
print(hasattr(p,"haha"))
fn = getattr(p,"haha")
fn()
delattr(p,"name")
設置屬性的例子
setattr(Person,"eat", lambda self:print("我要吃")) ps:person類 設置eat方法 經過匿名函數打印我要吃。
約束有一種方式
1.經過父類拋異常 raise ImplementedError 表明子類必須重寫這個方法
2.經過抽象類約束 沒有具體的實例。導入abc模塊的ABCmate 和abstractclass
from abc import ABCclass,abstractclass
class Foo(maetaclass=ABCclass):
@abstractclass
def login:pass
實例1:拋異常
class Foo:
def login(self):
#報錯,拋出異常
raise NotImplementedError("沒有重寫login")
class Member(Foo):
def login(self):
print("普通人員登陸")
class Member_admin(Foo):
def login(self):
print("吧務登陸")
class Admin(Foo):
def login(self):
print("管理員登陸")
def login(obj):
obj.login()
m = Member()
m_a = Member_admin()
a = Admin()
實例2抽象類
from abc import ABCMeta,abstractmethod
class Foo(metaclass=ABCMeta):
@abstractmethod
def login(self):pass
class Member(Foo):
def login(self):
print("普通人員登陸")
class Member_admin(Foo):
def login(self):
print("吧務登陸")
class Admin(Foo):
def login(self):
print("管理員登陸")
def login(obj):
obj.login()
m = Member()
m_a = Member_admin()
a = Admin()
login(m)
login(m_a)
login(a)
class A:
pass
class B(A):
pass
py2:
經典類 -> 默認不繼承object
新式類 -> 默認繼承object
py3:
新式類
萬事萬物皆爲對象 -> 全部的東西都要繼承object
__mro__() 查看繼承的順序
super(Branch, self).__init__(name,address)
super的兩種用法:
1.指定要從哪兒繼承方法過來
class A:
def test(self):
print("testA")
class B(A):
def test(self):
print("testB")
class C(B):
def test(self):
#print("testC")
super(B, self).test() super的第一個參數可根據想訪問那個方法來指定,若是想訪問A裏面的test 把一個參數寫成B便可
c = C()
c.test()
2.訪問父類裏面的構造方法
class School:
def __init__(self,name,adress):
self.name = name
self.address = adress
class Branch(School):
def __init__(self,name,address,leader):
self.leader = leader
super(Branch, self).__init__(name,address)
b = Branch("beida","shahe","Jackson")
print(b.name)
補充點:經過類建立對象 類是經過type來建立的,type是什麼鬼我也不知道......
__doc__ 打印類的描述信息
class Person:
"""計算a,b 的和"""
def __init__(self,name):
self.name = name
def eat(self,a,b):
return a+b
print(Person.__doc__)
__module__表示當前操做的對象在哪一個模塊
class M:
def __init__(self,name):
self.name = name
print(M.__module__) ps:結果是main
__class__表示當前操做的對象的類是什麼
__del__析構方法,當對象在內存中被釋放的時候自動執行
__call__對象後面加括號觸發執行
__dict__查看類或對象中的全部成員
__str__若是一個類中定義了str方法,打印對象時默認輸出該方法的返回值
__getitem__,__setitem__,__delitem__ 用於索引操做
class Foo(object):
def __getitem__(self, key):
print('__getitem__',key)
def __setitem__(self, key, value):
print('__setitem__',key,value)
def __delitem__(self, key):
print('__delitem__',key)
obj = Foo()
result = obj['k1'] # 自動觸發執行 __getitem__
obj['k2'] = 'alex' # 自動觸發執行 __setitem__
del obj['k1']
__new__用於建立實例的 在init方法前執行
__metaclass__ 定義一個類如何被建立
例子詳解:
class Person:
#c建立對象的時候自動調用init
def __init__(self):
print("我是特殊成員")
#在對象加括號的時候自動調用
def __call__(self):
print("我是call")
#with的時候自動調用
def __enter__(self):
print("我是enter")
#離開with的時候自動調用
def __exit__(self, exc_type, exc_val, exc_tb):
print("我是exit")
#執行[]會調用
def __getitem__(self, item):
print("我是getitem")
return "haha"
#執行p[key] = value的時候自動執行
def __setitem__(self, key, value):
print(key)
print(value)
def __delitem__(self, key):
pass
def __hash__(self): ps:hash必須返回一個數字
print("我是hash")
return 1
#z執行==的時候自動執行
def __eq__(self, other):
print("這是eq")
return True
#執行加的時候自動執行
def __add__(self, other):
print("這是加")
p = Person()
__new__詳細說明__new__在init以前執行
建立對象的時間軸,首先寫好一個類 而後加載類,
new開闢一個內存空間,(構造) 而後在執行init
建立類的時候若是不寫new自動執行object裏面的new開闢一個新的內存空間
1. 加載類 2. 開闢內存(__new__) 3. 初始化(__init__) 4. 使⽤用對象xxxxxxxxx
例子1:
class A:
def __init__(self):
print("我是init")
def __new__(cls, *args, **kwargs):
print("我是new")
return object.__new__(cls) #開闢內存
a = A() #不寫new默認使用object中的new
例子2:new的單例模式
#單例模式(惡漢式),在內存裏面保存一個對象,而且能反覆使用
class Singleton:
__instance = None
def __init__(self):
print("我是singleton")
def __new__(cls, *args, **kwargs):
if Singleton.__instance:
return Singleton.__instance
else:
obj = object.__new__(cls)
Singleton.__instance = obj
return Singleton.__instance
s1 = Singleton()
s2 = Singleton()
print(id(s1),id(s2))
#目前問題:高併發的狀況下,這個單例有問題
try:
xxxx
except 錯誤:
xxx
finally:
最終的...
traceback
查看調用過程的報錯信息
raise 拋出異常對象
定義類的時候繼承Exception就是異常類
try:
print("各類操做....")
except ZeroDivisionError as e:
print("除數不不能是0")
except FileNotFoundError as e:
print("⽂文件不不存在")
except Exception as e:
print("其餘錯誤")
else:
'''保護不不拋出異常的代碼, 當try中⽆無異常的時候執⾏行行'''
finally: '''最後老是要執⾏行行我'''
import traceback # 能夠看見堆棧信息(誰掉了誰)
try:
print(1/0)
except Exception:
print("報錯了")
print(traceback.format_exc()) #查看調用過程的報錯信息
自定義異常
class shujuleixingcuowu(Exception): #只要繼承了Exception就是異常類
pass
def func(a,b):
"""
計算a+b的結果
:param: a必須是數字
:param: b必須是數字
:return: 和
"""
if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
return a + b
else:
raise shujuleixingcuowu("a和b的數據類型錯誤")
修改@property屬性裏面的值
class Person:
def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name+"_sb"
@name.setter
def name(self,_name):
self.__name = _name
p = Person("Jack")
print(p.name)
p.name = "haha"
print(p.name)
import hashlib #機密包 最著名的是MD5用來驗證文件或者密碼的一致性
password = "123456"
obj = hashlib.md5()
obj.update(password.encode("utf-8")) #必須是字節
s = obj.hexdigest()
print(s)
加鹽
import hashlib
password = "123456"
obj = hashlib.md5(b'wang') 在這兒加
obj.update(password.encode("utf-8")) #必須是字節
s = obj.hexdigest()
print(s)
例子:實現登陸和註冊功能
import hashlib
username = ""
password = ""
def my_md5(s):
obj = hashlib.md5(b'asdasd')
obj.update(s.encode("utf-8"))
return obj.hexdigest()
def reg():
uname = input("請輸入用戶名:")
upwd = input("請輸入密碼:")
global username
username = uname
global password
password = my_md5(upwd)
print(password)
def login():
uname = input("請輸入用戶名:")
upwd = input("請輸入密碼:")
if uname == username and my_md5(upwd) == password:
print("登陸成功")
else:
print("登陸失敗")
reg()
login()
單文件記錄日誌
#logging 記錄日誌
import logging
# filename: ⽂文件名
# format: 數據的格式化輸出. 最終在⽇日誌⽂文件中的樣⼦子
# 時間-名稱-級別-模塊: 錯誤信息
# datefmt: 時間的格式
# level: 錯誤的級別權重, 當錯誤的級別權重⼤大於等於leval的時候纔會寫⼊入⽂文件
logging.basicConfig(filename='x1.txt',
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=0) # 當前配置表示 10以上的分數會被寫⼊入⽂文件
logging.critical("報錯了") #最高級別#50
logging.error("報錯了") #40
logging.warn("1")
logging.warning("警告") #警告30
logging.info("信息")
logging.debug("調錯") #10
logging.log(999,"地球飛了")
結合自定義異常類打印日誌
#logging 記錄日誌
import logging
# # filename: ⽂文件名
# # format: 數據的格式化輸出. 最終在⽇日誌⽂文件中的樣⼦子
# # 時間-名稱-級別-模塊: 錯誤信息
# # datefmt: 時間的格式
# # level: 錯誤的級別權重, 當錯誤的級別權重⼤大於等於leval的時候纔會寫⼊入⽂文件
logging.basicConfig(filename='x1.txt',
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=0) # 當前配置表示 10以上的分數會被寫⼊入⽂文件
logging.critical("報錯了") #最高級別#50
logging.error("報錯了") #40
logging.warn("1")
logging.warning("警告") #警告30
logging.info("信息")
logging.debug("調錯") #10
logging.log(999,"地球飛了")
import logging
import traceback
class JackError(Exception):
pass
for i in range(10):
try:
if i % 3 ==0:
raise FileNotFoundError("文件不存在")
elif i % 3 == 1:
raise KeyError
elif i % 3 == 2:
raise JackError("Jackexception")
except FileNotFoundError:
val = traceback.format_exc()
logging.error(val)
except KeyError:
val = traceback.format_exc()
logging.error(val)
except JackError:
val = traceback.format_exc()
logging.error(val)
except Exception:
val = traceback.format_exc()
logging.error(val)
多日誌文件系統
import logging
# 建立⼀一個操做⽇日誌的對象logger(依賴FileHandler)
file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s"))
logger1 = logging.Logger('用戶名1', level=logging.ERROR)
logger1.addHandler(file_handler)
logger1.error("錯了錯了")
# 再建立⼀一個操做⽇日誌的對象logger(依賴FileHandler
file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s %(levelname)s -%(module)s: %(message)s"))
logger2 = logging.Logger('用戶名2', level=logging.ERROR)
logger2.addHandler(file_handler2)
logger2.error("好像真的錯了")