Python之路【第八篇】:Python模塊

来源:https://www.cnblogs.com/hackerer/archive/2019/04/22/10753752.html
-Advertisement-
Play Games

閱讀目錄 一、模塊和包 模塊(module)的概念: 在電腦程式的開發過程中,隨著程式代碼越寫越多,在一個文件里代碼會越來越長,越來越不容易維護。 為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少,很多編程語言都採用這種組織代碼的方式。在Pytho ...


閱讀目錄

一、模塊和包

模塊(module)的概念:

在電腦程式的開發過程中,隨著程式代碼越寫越多,在一個文件里代碼會越來越長,越來越不容易維護。

為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少,很多編程語言都採用這種組織代碼的方式。在Python中,一個.py文件就稱之為一個模塊(module)。

使用模塊有哪些好處?

1、最大的好處就是大大提高了代碼的可維護性。
2、編寫代碼不必從零開始。當一個模塊編寫完成,就可以被其他地方調用。我們在編寫程式的時候,也經常飲用其他模塊,包括Python內置的模塊和來自第三方的模塊。

模塊一共分為三種:

1、python標準庫
2、第三方模塊
3、應用程式自定義模塊

註意:

使用模塊還可以避免函數名跟變數名衝突。相同名字的函數和變數完全可以分別存在不同的模塊中,因此,我們在自己編寫模塊時,不必考慮名字會與其他模塊衝突。但是也要註意,儘量不要與內置函數名字衝突。

二、模塊的導入方法

1、import語句

import module1,[module2[,...moduleN]]

當我們使用import語句的時候,Python解釋器是怎樣找到對應的文件?答案就是解釋器有自己的搜索路徑,存在sys.path里。

import sys
print(sys.path)

運行結果如下:
['G:\\python_s3\\day21', 'G:\\python_s3', 'C:\\Python35\\python35.zip', 'C:\\Python35\\DLLs', 'C:\\Python35\\lib', 'C:\\Python35', 'C:\\Python35\\lib\\site-packages', 'D:\\Program Files (x64)\\pycharm軟體安裝\\config\\PyCharm 2018.3\\helpers\\pycharm_matplotlib_backend']

因此若像我一樣在當前目錄下存在與要引入模塊同名的文件,就會把要引入的模塊沒屏蔽掉。

2、from...import ...語句

from modname import name1[,name2[, ... nameN]]

這個聲明不會把整個modulename模塊導入到當前的命名空間中,只會講它裡面的name1或name2單個引入到執行這個聲明的模塊的全局符號表。 

3、from...import*語句

from modname import *

4、運行本質

1、import test
2、from test import add

無論1還是2,首先通過sys.path找到test.py,然後執行test腳本,區別是1會將test這個變數名載入到名字空間,而2只會將add這個變數名載入進來。

5、包(package)

1、如果不同的人編寫的模塊名相同怎麼辦?為了避免模塊名衝突,Python又引入了按目錄來組織模塊的方法,成為包(Package)。
舉個例子:一個abc.py的文件就是一個名字叫abc的模塊,一個simon.py的文件就是一個叫simon的模塊。
現在,假設我們的abc和simon這兩個模塊名字和其他模塊起衝突了,於是我們可以通過包來組織模塊,從而避免衝突。方法就是選擇一個頂層包名:


2、引入了包以後,只要頂層的包名不與別人衝突,那所有模塊都不會與別人衝突。現在,view.py模塊的名字就變成了hello_django.app01.views,類似的,manage.py的模塊名則是hello_django.manage。

請註意,每一個包目錄下麵都會有一個__init__.py的文件,這個文件是必須存在的,否則,Python就把這個目錄當成普通目錄(文件夾),而不是一個包。__init__.py可以是空文件,也可以有Python代碼,因為__init__.py本身就是一個模塊,而它的模塊名就是對應包的名字。

註意點(important)

調用包就是執行包下的__init__.py文件

#1--------------------------------
在node1中import hello是找不到的,有人說可以找到呀,那是因為你的pycharm為你把myapp這一層路徑加入到了sys.path裡面,所以可以找到,然而程式一旦在命令行運行,則報錯。有同學問那怎麼辦?簡單啊,自己把這個路徑加進去不就OK啦:


import sys,os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) #臨時修改
import hello
hello.hello1()
#2、--------------
if __name__=='__main__':
    print('ok')

“Make a .py both importable and executable”

如果我們是直接執行某個.py文件的時候,該文件中那麼"__name__ == '__main__' "是True,但是我們如果從另外一個.py文件通過import導入該文件的時候,這時__name__的值就是我們這個py文件的名字而不是__main__.

這個功能還有一個用處:調試代碼的時候,在"if __name__ == '__main__' "中加入一些我們的調試代碼,我們可以讓外部模塊調用的時候不執行我們的調試代碼,但是如果我們想排查問題的時候,直接執行該模塊文件,調試代碼能夠正常運行!

##-------------cal.py
def add(x,y):
 
    return x+y
##-------------main.py
import cal      #from module import cal
 
def main():
 
    cal.add(1,2)
     
##--------------bin.py
from module import main
 
main.main()

註意:

 

# from module import cal 改成 from . import cal同樣可以,這是因為bin.py是我們的執行腳本,
# sys.path里有bin.py的當前環境。即/Users/simon/Desktop/whaterver/project/web這層路徑,
# 無論import what ,  解釋器都會按這個路徑找。所以當執行到main.py時,import cal會找不到,因為
# sys.path里沒有/Users/simon/Desktop/whaterver/project/web/module這個路徑,而
#  from  module/.  import cal 時,解釋器就可以找到了。

三、time模塊(* * * *)

三種時間表示

在Python中,通常有這幾種方式來表達時間:
1、時間戳(timestamp):通常來說,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。我們運行“type(time.time())”,返回的是float類型。
2、格式化的時間字元串
3、元祖(struct_time):struct_time元祖共有9個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時)
import time

#1、time():  返回當前時間的時間戳
print(time.time())

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day21/example.py
1555996405.5020845

#2、localtime(secs):  將一個時間戳轉換為當前時區的struct_time。secs參數未提供,則以當前時間為準。
print(time.localtime())

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day21/example.py
time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=13, tm_min=18, tm_sec=9, tm_wday=1, tm_yday=113, tm_isdst=0)

#3、gmtime([secs])和localtime()方法類似,gmtime()方法是將一個時間戳轉換為UTC時區(0時區)的struct_time。
print(time.gmtime())

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day21/example.py
time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=5, tm_min=21, tm_sec=25, tm_wday=1, tm_yday=113, tm_isdst=0)

#4、mktime(t):  將一個struct_time轉化為時間戳
print(time.mktime(time.localtime())) #

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day21/example.py
1555998160.0

#5、asctime([t]):  把一個表示時間的元祖或者struct_time表示為這種形式:'Tue Apr 23 13:45:49 2019'

#如果沒有參數,將會將time.localtime()作為參數傳入。
print(time.asctime())

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day21/example.py
Tue Apr 23 13:45:49 2019


#6、ctime([secs]):  把一個時間戳(按秒計算的浮點數)轉化為time.asctime()的形式。如果參數未給或者為None的時候,將會預設time.time()為參數。它的作用相當於time.asctime(time.localtime(secs))。

print(time.ctime())  #Tue Apr 23 14:02:45 2019

print(time.ctime(time.time()))  #Tue Apr 23 14:03:50 2019


#7、strftime(format[,t])  #把一個代表時間的元祖或者struct_time(如由time.localtime()和time.gmtime()返回)  轉化為格式化的時間字元串。如果t未指定,將傳入time.localtime()。如果元組中任何一個元素過界,ValueError的錯誤將會被拋出。

print(time.strftime("%Y-%m-%d %X",time.localtime()))  #2019-04-23 14:11:12


#8、time.strptime(string[, format])  #把一個格式化時間字元串轉化為struct_time。實際上它和strftime()是逆操作。

print(time.strptime('2019-04-23 14:15:07', '%Y-%m-%d %X'))

輸出結果為:
time.struct_time(tm_year=2019, tm_mon=4, tm_mday=23, tm_hour=14, tm_min=15, tm_sec=7, tm_wday=1, tm_yday=113, tm_isdst=-1)

#在這個函數中,format預設為:"%a %b %d %H:%M:%S %Y"。

#9、sleep(sesc)
print(time.sleep(3))   #線程推遲指定的時間運行,單位為秒。


#10、clock

# 這個需要註意,在不同的系統上含義不同。在UNIX系統上,它返回的是"進程時間",它是用秒錶示的浮點數(時間戳)。而在windows中,第一次調用,返回的是進程運行的實際時間。而第二次之後的調用是自第一次調用以後到現在的運行時間,即兩次時間差。

關係圖:

四、random模塊(* *)

import random

ret=random.random()
# ret=random.randint(1,3)  #[1,3]
# ret=random.randrange(1,3)  #[1,3]
# ret=random.choice([11,22,33,44,55])
# ret=random.sample([11,22,33,44,55],2)
# ret=random.uniform(1,4)
# print(ret)
# ret=[1,2,3,4,5]
# random.shuffle(ret)
# print(ret)

item=[1,3,5,7,9]
random.shuffle(item)
print(item)

#隨機生成驗證碼

import random
def v_code():

    ret=""
    for i in range(5):
        num=random.randint(0,9)
        alf=chr(random.randint(65,122))

        s=str(random.choice([num,alf]))
        ret+=s
    return ret
print(v_code())

五、os模塊(* * * *)

os模塊是與操作系統交互的介面

os.getcwd()  #獲取當前工作目錄,即當前python腳本的目錄路徑

os.chdir("dirname")  #改變當前腳本工作目錄,相當於shell下cd

os.cudir  #返回當前目錄:(' . ')

os.pardir   #獲取當前目錄的父目錄字元串名:(' . . ')

os.makedirs('dirname1/dirname2')  #可生成多層遞歸目錄

os.removedirs('dirname1')  #若目錄為空,則刪除,並遞歸到上一級目錄,如若也為空,則刪除,依此類推

os.mkdir('dirname')  #生成單級目錄,相當於linux中mkdir dirname

os.rmdir('dirname')   #刪除單級空目錄,若目錄不為空則無法刪除,報錯,相當於shell中rmdir dirname

os.listdir('dirname')  #列出指定目錄下的所有文件和子目錄,包含隱藏文件,並以列表的方式列印

os.remove()  #刪除一個文件

os.rename("oldname","newname")  #重命名文件/目錄

os.stat('path/filename')   #獲取文件/目錄信息
例:
print(os.stat("sss.py"))
C:\Python35\python3.exe G:/python_s3/day22/os_test.py
os.stat_result(st_mode=33206, st_ino=11821949021847676, st_dev=2159804260, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1556025329, st_mtime=1556025329, st_ctime=1556025302)

os.sep   #輸出操作系統特定的路徑分隔符,win下為"\\",Linux下為"/"

os.linesep  #輸出當前平臺使用的行終止符,win下為"\r\n",Linux下為"\n"

os.pathsep   #輸出用於分隔文件路徑的字元 win下為; ,Linux下為:

os.name   #輸出字元串指示當前使用平臺。win-->'nt'; Linux-->'posix'

os.system("bash command")   #運行shell命令,直接顯示

os.environ   #獲取系統環境變數
例:
print(os.environ)
environ({'FP_NO_HOST_CHECK': 'NO', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM': 'D:\\Program Files (x64)\\pycharm軟體安裝\\config\\PyCharm 2018.3\\bin;', 'COMPUTERNAME': 'DELL-PC', 'PYTHONPATH': 'G:\\python_s3;D:\\Program Files (x64)\\pycharm軟體安裝\\config\\PyCharm 2018.3\\helpers\\pycharm_matplotlib_backend', 'PYCHARM_HOSTED': '1', 'PYCHARM_MATPLOTLIB_PORT'

os.path.abspath(path)   #返回path規範化的絕對路徑

os.path.split(path)   #將path分割成目錄和文件名二元組返回
例:
print(os.path.split(r"G:\python_s3\day22\sss.py"))
輸出結果:
('G:\\python_s3\\day22', 'sss.py')

os.path.dirname(path)   #返回path的目錄。其實就是os.path.split(path)的第一個元素
例:
print(os.path.dirname(r"G:\python_s3\day22\sss.py"))
輸出結果:
G:\python_s3\day22

os.path.basename(path)   #返回path最後的文件名,如果path以/ 或 \結尾,那麼就會返回空值。即os.path.split(path) 的第二個元素
例:
print(os.path.basename(r"G:\python_s3\day22\sss.py"))
輸出結果:
sss.py

os.path.exists(path)   #如果path存在,返回True;如果path不存在,返回False

os.path.isabs(path)   #如果path是絕對路徑,返回True

os.path.isfile(path)   #如果path是一個存在的文件,返回True,否則返回False

os.path.isdir(path)   #如果path是一個存在的目錄,則返回True,否則返回False

os.path.join(path1,paht2[,  ...])   #將多個路徑組合後返回,第一個絕對路徑之前的參數將被忽略
例:
a="G:\python_s3\day22"
b="sss.py"

print(os.path.join(a,b))
輸出結果:
G:\python_s3\day22\sss.py

os.path.getatime(paht)   #返回path所指向的文件或者目錄的最後存取時間

os.path.getmtime(path)   #返回path所指向的文件或者目錄的最後修改時間

三、實現裝飾器知識儲備

裝飾器=高階函數+函數嵌套+閉包

四、高階函數

高階函數的定義:
1、函數接收的參數是一個函數名
2、函數的返回值是一個函數名
3、滿足上述條件任意一個,都可稱之為高階函數

 

 

五、函數嵌套

def father(name):
    print('from father %s' %name)
    def son():
        print('from the son')
        def grandson():
            print('from the grandson')
        grandson()
    son()

father('朱銳')

六、閉包

1、閉包

def father(name):
    print('from father %s' %name)
    def son():
        print('from the son')
        def grandson():
            print('from the grandson')
        grandson()
    son()

father('朱銳')

'''
閉包
'''

def father(name):
    def son():
        # name='simon1'
        print('我的爸爸是%s' %name)
        def grandson():
            print('我的爺爺是%s' %name)
        grandson()
    son()
father('simon')

2、函數閉包裝飾器基本實現

import time
def timmer(func):
    def wrapper():
        # print(func)
        start_time=time.time()
        func() #就是在運行test()
        stop_time=time.time()
        print('運行時間是%s' %(stop_time-start_time))
    return wrapper
@timmer #語法糖,這個是重點

def test():
    time.sleep(3)
    print('test函數運行完畢')

# res=timmer(test) #返回的是wrapper的地址
# res() #執行的是wrapper()

# test=timmer(test) #返回的是wrapper的地址
# test() #執行的是wrapper()

test()
'''
語法糖
'''
# @timmer #就相當於 test=timmer(test)

3、函數閉包加上返回值

#未加返回值
import time
def timmer(func):
    def wrapper():
        # print(func)
        start_time=time.time()
        func() #就是在運行test()
        stop_time=time.time()
        print('運行時間是%s' %(stop_time-start_time))
        return 123
    return wrapper
@timmer #語法糖

def test():
    time.sleep(3)
    print('test函數運行完畢')
    return '這是test的返回值'
res=test() #就是在運行wrapper
print(res)

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day20/加上返回值.py
test函數運行完畢
運行時間是3.000171661376953
123
#加上返回值
import time
def timmer(func):
    def wrapper():
        # print(func)
        start_time=time.time()
        res=func() #就是在運行test()     ##主要修改這裡1
        stop_time=time.time()
        print('運行時間是%s' %(stop_time-start_time))
        return res     ##修改這裡2
    return wrapper
@timmer #語法糖

def test():
    time.sleep(3)
    print('test函數運行完畢')
    return '這是test的返回值'
res=test() #就是在運行wrapper
print(res)

運行結果如下:
C:\Python35\python3.exe G:/python_s3/day20/加上返回值.py
test函數運行完畢
運行時間是3.000171661376953
這是test的返回值

4、函數閉包加上參數

import time
def timmer(func):
    def wrapper(name,age):   #加入參數,name,age
        # print(func)
        start_time=time.time()
        res=func(name,age) ##加入參數,name,age
        stop_time=time.time()
        print('運行時間是%s' %(stop_time-start_time))
        return res
    return wrapper
@timmer #語法糖

def test(name,age): #加入參數,name,age
    time.sleep(3)
    print('test函數運行完畢,名字是【%s】,年齡是【%s】' % (name,age))
    return '這是test的返回值'
res=test('simon',18) #就是在運行wrapper
print(res)

使用可變長參數代碼如下:達到的效果是傳參靈活

import time
def timmer(func):
    def wrapper(*args,**kwargs): #test('simon',18)  args=('simon') kwargs={'age':18}
        # print(func)
        start_time=time.time()
        res=func(*args,**kwargs) #就是在運行test()     func(*('simon'),**{'age':18})
        stop_time=time.time()
        print('運行時間是%s' %(stop_time-start_time))
        return res
    return wrapper
@timmer #語法糖

def test(name,age):
    time.sleep(3)
    print('test函數運行完畢,名字是【%s】,年齡是【%s】' % (name,age))
    return '這是test的返回值'
def test1(name,age,gender):
    time.sleep(1)
    print('test函數運行完畢,名字是【%s】,年齡是【%s】,性別是【%s】' % (name,age,gender))
res=test('simon',18) #就是在運行wrapper
print(res)

test1('simon',18,'male')

 

5、裝飾器的使用

#無參裝飾器
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()
#有參裝飾器
def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == 'file':
                if name == 'simon' and pwd == '123':
                    print('login successful')
                    res=func(*args,**kwargs)
                    return res
            elif driver == 'ldap':
                print('ldap')
        return wrapper
    return auth2

@auth(driver='file')
def foo(name):
    print(name)

foo('simon')

 #驗證功能裝飾器

#驗證功能裝飾器
user_list=[
    {'name':'simon','passwd':'123'},
    {'name':'zhurui','passwd':'123'},
    {'name':'william','passwd':'123'},
    {'name':'zhurui1','passwd':'123'},
]
current_dic={'username':None,'login':False}


def auth_func(func):
    def wrapper(*args,**kwargs):
        if current_dic['username'] and current_dic['login']:
            res=func(*args,**kwargs)
            return res
        username=input('用戶名:').strip()
        passwd=input('密碼:').strip()
        for user_dic in user_list:
            if username == user_dic['name'] and passwd == user_dic['passwd']:
                current_dic['username']=username
                current_dic['login']=True
                res=func(*args,**kwargs)
                return res
        else:
            print('用戶名或者密碼錯誤')

        # if username == 'simon' and passwd == '123':
        #     user_dic['username']=username
        #     user_dic['login']=True
        #     res=func(*args,**kwargs)
        #     return res
        # else:
        #     print('用戶名或密碼錯誤')
    return wrapper

@auth_func
def index():
    print('歡迎來到某寶首頁')
@auth_func
def home(name):
    print('歡迎回家%s' %name)
@auth_func
def shopping_car(name):
    print('%s購物車裡有[%s,%s,%s]' %(name,'餐具','沙發','電動車'))

print('before----->',current_dic)
index()
print('after---->',current_dic)
home('simon')
# shopping_car('simon')

#帶參數驗證功能裝飾器

#帶參數驗證功能裝飾器
user_list=[
    {'name':'simon','passwd':'123'},
    {'name':'zhurui','passwd':'123'},
    {'name':'william','passwd':'123'},
    {'name':'zhurui1','passwd':'123'},
]
current_dic={'username':None,'login':False}

def auth(auth_type='filedb'):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print('認證類型是',auth_type)
            if auth_type == 'filedb':
                if current_dic['username'] and current_dic['login']:
                    res = func(*args, **kwargs)
                    return res
                username=input('用戶名:').strip()
                passwd=input('密碼:').strip()
                for user_dic in user_list:
                    if username == user_dic['name'] and passwd == user_dic['passwd']:
                        current_dic['username']=username
                        current_dic['login']=True
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('用戶名或者密碼錯誤')
            elif auth_type == 'ldap':
                print('這玩意沒搞過,不知道怎麼玩')
                res = func(*args, **kwargs)
                return res
            else:
                print('鬼才知道你用的什麼認證方式')
                res = func(*args, **kwargs)
                return res

        return wrapper
    return auth_func

@auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一個auth_type  --->index=auth_func(index)
def index():
    print('歡迎來到某寶主頁')

@auth(auth_type='ldap')
def home(name):
    print('歡迎回家%s' %name)
#
@auth(auth_type='sssssss')
def shopping_car(name):
    print('%s的購物車裡有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# home('simon')
shopping_car('simon')

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 這是一篇面向對象作業總結,作業內容是模擬電梯調度,一共有三個階段,具體要求不詳述,第一階段只要求先來先服務電梯,第二次支持捎帶,第三次則需要多部電梯協調,通過換乘來完成請求。本次作業在優化方面效果不佳。設計比較統一,設計原則檢查放在最後。 第5次作業 類圖如下: 說明: 具體的來說,M是主入 ...
  • 騰訊雲伺服器 點擊添加紀錄,紅色框框裡面填寫自己的公網IP即可。 阿裡雲上搭建php+mysql服務,並使用ftp將本地php文件及資料庫文件上傳到伺服器 先搭建php+MySQL環境 下載 "xampp" 。 XAMPP(Apache+MySQL+PHP+PERL)是一個功能強大的建站集成軟體包。 ...
  • @ "TOC" 1.變數 變數用於存儲要在電腦程式中引用和操作的信息。它們的唯一目的是在記憶體中標記和存儲數據。然後可以在整個程式中使用這些數據。變數存儲在記憶體中的值。這就意味著在創建變數時會在記憶體中開闢一個空間。 基於變數的數據類型,解釋器會分配指定記憶體,並決定什麼數據可以被存儲在記憶體中。因此,變 ...
  • NumPy: 1、NumPy 是一個功能強大的第三方庫(需要自己安裝),主要用於對多維數組執行計算; 它提供了大量的庫函數和操作,可以幫助程式員更輕鬆地進行數值計算 2、可以和另外兩個第三方庫 SciPy 和 Matplotlib 一起使用從而在一定程度上替換對 Matlab 的使用 3、主要應用: ...
  • R語言基礎學習——D02 20190423內容綱要: 1、前言 2、向量操作 (1)常規操作 (2)不定長向量計算 (3)序列 (4)向量的刪除與保留 3、列表詳解 (1)列表的索引 (2)列表得元素屬性 (3)更改列表元素 (4)刪除列表元素 (5)合併兩個列表 (6)將列表轉換為向量 4、推薦 ...
  • 一、引言 大部分系統都離不開數據訪問,資料庫包括SQL和NOSQL,SQL是指關係型資料庫,常見的有SQL Server,Oracle,MySQL(開源),NOSQL是泛指非關係型資料庫,常見的有MongoDB,Redis。 用spring開發時我們常用的ORM框架有JDBC、Mybatis,Hib ...
  • java.util.logging.Logger——java 中提供的日誌類 實際開發 90% 都是使用 log4j 記錄日誌,而 Log4j 底層就是 java.util.logging.Logger 實現的 Log4j 是一個日誌輸出框架,就是用於輸出日誌的。Mybatis 的日誌輸出是通過 L ...
  • 1.cd 到指定目錄 2.運行命令 python 3之前 python 3+ 3.運行後: 4.在瀏覽器輸入 http://localhost:8888/. 測試,然後就可以瀏覽網頁 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...