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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...