day07 類

1、目錄

1.模塊python

2.包併發

3.isinstance issubclass typeapp

4.方法和函數函數

5.反射高併發

6.約束測試

7.繼承this

8.特殊成員spa

9.異常處理debug

補充知識點日誌

10.hashlib模塊

11.logging日誌模塊

2、內容

一.模塊

 模塊的概述:模塊本質上就是一個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 issubclass type

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)

十.hashlib模塊

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日誌模塊

單文件記錄日誌

#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("好像真的錯了")
相關文章
相關標籤/搜索