python面向對象基礎

来源:https://www.cnblogs.com/xiaoyafei/archive/2018/05/25/9090431.html
-Advertisement-
Play Games

面向對象基礎 編程範式 所謂的面向對象編程,指的就是一種編程範式,那麼什麼是編程範式呢?就是 按照某種語法風格加上數據結構加上演算法來編寫程式 。 數據結構:列表、字典、集合 演算法:編寫程式的邏輯或者解決問題的流程 一個程式是程式員為了得到一個任務結果而編寫的一組指令的集合,正所謂跳跳大陸通羅馬,實現 ...


面向對象基礎

編程範式

所謂的面向對象編程,指的就是一種編程範式,那麼什麼是編程範式呢?就是按照某種語法風格加上數據結構加上演算法來編寫程式

  • 數據結構:列表、字典、集合
  • 演算法:編寫程式的邏輯或者解決問題的流程

一個程式是程式員為了得到一個任務結果而編寫的一組指令的集合,正所謂跳跳大陸通羅馬,實現一個任務的方式有很多種不同的方式,對這些不同的編程方式的特點進行歸納總結得出來的編程方式類別,即為編程範式。

不同的編程範式本質上代表對各種類型的任務採取的不同的解決問題的思路,大多數語言只支持一種編程範式,當然也有些語言可以同時支持多種編程範式。兩種最重要的編程範式分別是面向過程編程面向對象編程

面向過程編程

面向過程編程,核心就是過程二字,過程指的是解決問題的步驟,就是先乾什麼,然後乾什麼,最後乾什麼?實際上就相當於設計了一條流水線,就是機械式的思維方式,把一個大問題拆分成若幹個小問題,然後一個個小問題再細化,然後再把這些小問題組合起來,就解決了一個大問題。

下麵來看下麵向過程的編程,讓用戶輸入註冊信息:

import json
import re
def interactive():  # 接收用戶輸入
    name = input('>>>').strip()
    pwd = input('>>').strip()
    return {
        'name':name,
        'pwd':pwd
    }
def check(user_info):  # 檢測
    is_valid = True
    if len(user_info['name']) == 0:
        print('用戶名不能為空!')
        is_valid = False
    if len(user_info['pwd']) < 6:
        print('密碼不能少於6位!')
        is_valid = False
    return {
        'is_valid':is_valid,
        'user_info':user_info
    }
def register(check_info):  # 寫入資料庫中
    if check_info['is_valid']:  # 如果為真
        with open('db.json','w',encoding='utf-8') as f:
            json.dump(check_info['user_info'],f)

def main():  # 主函數
    user_info = interactive()
    check_info = check(user_info)
    register(check_info)

if __name__ == '__main__':
    main()

那麼這段程式的運行結果就是提示輸入用戶名和密碼,然後對用戶名和密碼進行檢測,如果符合規則,那麼就將寫入資料庫中。

那麼此時,如果我想讓用戶再註冊信息的時候,再加上郵箱,代碼是怎麼寫的呢?

import json
import re
def interactive():  # 接收用戶輸入
    name = input('>>>').strip()
    pwd = input('>>').strip()
    email = input('>>').strip()
    return {
        'name':name,
        'pwd':pwd,
        'email':email
    }
def check(user_info):  # 檢測
    is_valid = True
    if len(user_info['name']) == 0:
        print('用戶名不能為空!')
        is_valid = False
    if len(user_info['pwd']) < 6:
        print('密碼不能少於6位!')
        is_valid = False
     if not re.search(r'@.*?\.com$',user_info['email']):
        print('郵箱格式不合法!')
        is_valid = False
    return {
        'is_valid':is_valid,
        'user_info':user_info
    }
def register(check_info):  # 寫入資料庫中
    if check_info['is_valid']:  # 如果為真
        with open('db.json','w',encoding='utf-8') as f:
            json.dump(check_info['user_info'],f)

def main():  # 主函數
    user_info = interactive()
    check_info = check(user_info)
    register(check_info)

if __name__ == '__main__':
    main()

如果我們還要添加來自國家、性別、年齡這些信息,這整個代碼流程不都要繼續修改嗎?那麼我們現在就能看出面向過程的優缺點了:

優點:把複雜的問題流程化,進而簡單化

缺點:可擴展性差

應用場景:自動部署、系統監控腳本

面向對象編程

面向對象編程,核心就是對象二字,就是站在上帝的視角:所有存在的事物都是i對象

舉個例子說明:在西游記中,如來就是上帝,他想要解決的問題就是如何把經書傳入大唐,如果是面向過程來說,如來就要想這條路要怎麼走,碰到事情的時候應該怎麼處理,就是要把取經的過程全部都要考慮到,然而換成面向對象呢?他找來了唐僧、孫悟空等人,妖魔鬼怪,一大堆神仙開始了取經之路...

我和小明的特征都是對象,我們的特征都是有鼻子有眼睛、兩隻手兩條腿,技能就是吃飯、學習、睡覺,所以我們可以被稱為對象。

為什麼你不會覺得你面前的筆記本不是孫悟空呢?因為筆記本有顯示器、鍵盤、滑鼠,而孫悟空有毛臉雷公嘴、會七十二變、有火眼金晶,所以你不會這樣覺得。

所謂的對象:就是特征和技能的結合體

面向過程:設計流程化

面向過程:站在上帝的視角來模擬世界

​ 優點:可擴展性高

​ 缺點:編程複雜度高

​ 應用場景:用戶需求經常變更:互聯網應用,游戲,企業內部應用

面向對象程式設計

在軟體質量屬性上,成本、性能、安全性、可擴展性都是必須要有的,但是可擴展性占的比例還是比較高的。

類即類別、種類,是面向對象設計最重要的概念。剛剛我們知道對象是特征和技能的結合體,那麼類就是一系列對象相似的特征與技能的結合體

那麼問題來了,先有的一個個具體存在的對象(比如一個具體存在的人),還是先有人類這個概念,這個問題需要分兩種情況去看

  • 在現實世界中,肯定是先有的對象,然後才有的類
世界上肯定是先出現各種各樣的實際存在的物體,然後隨著人類文明的發展,人類站在不同的角度總結出了不同的種類,比如人類、動物類、植物類等概念。也就說,對象是具體的存在,而類僅僅只是一個概念,並不真實存在,比如你無法告訴我人類具體指的是哪一個人。
  • 在程式中,務必先保證先定義類,後產生對象
與函數的使用是類似的:先定義函數,後調用函數,類也是一樣的:在程式中需要先定義類,後調用類。不一樣的是:調用函數會執行函數體代碼返回的是函數體執行的結果,而調用類會產生對象,返回的是對象

定義類

按照上面步驟,我們來先定義一個類(站在學校的角度,我們都是學生)

  • 在現實世界中,先有對象,然後才有的對象
對象1:李坦克
    特征: 
        學校:zhcpt
        姓名:李坦克
        性別:男
        年齡:18
    技能:
        學習
        吃飯
        睡覺
對象2:王大炮
    特征:
        學校:zhcpt
        姓名:王大炮
        性別:男
        年齡:23
    技能:
        學習
        吃飯
        睡覺
對象3:張小麗
    特征:
        學校:zhcpt
        姓名:張小麗
        性別:女
        年齡:16
    技能:
        學習
        吃飯
        睡覺

現實中的學生類:
    相似的特征:
        學校 = zhcpt
    相似的技能:
        學習
        吃飯
        睡覺
  • 在程式中,務必保證:先定義類,然後使用類(產生對象)
# 在python中程式中的類用class關鍵字定義。而在程式中特征用變數標識,技能用函數表示,因而類中最常見的無非是:變數和函數的定義

# 先定義類
class zhcptStundet:
    school = 'zhcpt'  # 相同的特征
    def learn(self):  # 相同的屬性
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
        
# 後產生對象
zhcptStudent()

產生一個對象,不是去執行類體,而是執行這個類體後會得到一個返回值。這個返回值就是對象,在這個過程中也被稱為實例化。所以應該是這樣的:

stu1 = zhcptStudent()  # 類的實例化
print(stu1)  # <__main__.zhcptStundet object at 0x0000013557F00438>

print(stu1)則是列印zhcptStudent這個類產生的對象,是這個對象的記憶體地址

註意:

  • 類中可以有任意的python代碼,這些代碼在類定義階段便會執行,因而會產生新的名稱空間,用來存放類的變數名和函數,可以通過zhcptStundet.__dict__方法去查看
  • 類中定義的名字,都是類的屬性,點是訪問屬性的語法
  • 對於經典類來說,我們可以通過該字典去操作類名稱空間的名字,但新式類有限制
# 定義類
class zhcptStudent:
    school = 'zhcpt'  # 類的數據屬性,定義新的名字,新的命名空間
    def learn(self):  # 類的函數屬性,定義了函數,產生了函數局部名稱空間,把函數內部定義的名字放進去
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')
    
# 查看類的名稱空間
print(zhcptStudent.__init__)

我們剛剛說類在定義階段時候便會執行,因而會產生新的名稱空間,用來存放類的變數名和函數,可以通過方法去查看,運行結果為:

----------run-----------
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStundet.learn at 0x0000022B584A0C80>, 'eat': <function zhcptStundet.eat at 0x0000022B584A0D08>, 'sleep': <function zhcptStundet.sleep at 0x0000022B584C90D0>, '__dict__': <attribute '__dict__' of 'zhcptStundet' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStundet' objects>, '__doc__': None}

所以類和函數就有了區別:函數在定義完成之後不調用的話,那麼這段函數就不會執行,而類在定義階段就會執行

針對屬性,python提供了專門的屬性訪問語法,現在我們來查看訪問下變數屬性的值、函數屬性的值

print(zhcptStudent.school)
print(zhcptStudent.learn)

運行結果為:

zhcpt
<function zhcptStudent.learn at 0x000001D94F020C80>  # 列印的是這個類下的learn函數記憶體地址

剛剛我們說,可以通過字典的方式去操作類名稱空間的名字,讓我們來看一下:

print(zhcptStudent.__dict__['school'])
print(zhcptStudent.__dict__['learn'])

運行結果和上面是一樣的:

zhcpt
<function zhcptStudent.learn at 0x0000023D2EAB0C80>

其實,我們很早之前就接觸過類了,還記得我們之前學過了list、dict嗎?記得time嗎?

In [2]: print(list)
<class 'list'>

In [3]: print(dict)
<class 'dict'>

# time本身也是一個類
import time
time.sleep  # 其中time是類,sleep是類里定義的函數屬性

類的操作

class zhcptStudent:
    school = 'zhcpt'  
    def learn(self):  
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')

增加

zhcptStudent.country = 'CN'
print(zhcptStudent.__dict__)
print(zhcptStudent.country)

# 運行結果
----------run-----------
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStudent.learn at 0x00000233B8D10C80>, 'eat': <function zhcptStudent.eat at 0x00000233B8D10D08>, 'sleep': <function zhcptStudent.sleep at 0x00000233B8D390D0>, '__dict__': <attribute '__dict__' of 'zhcptStudent' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStudent' objects>, '__doc__': None, 'country': 'CN'}
CN

刪除

del zhcptStudent.country
print(zhcptStudent.__dict__)

# 運行結果,已經找不到country這個k了
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStudent.learn at 0x000001EEF1380C80>, 'eat': <function zhcptStudent.eat at 0x000001EEF1380D08>, 'sleep': <function zhcptStudent.sleep at 0x000001EEF13A90D0>, '__dict__': <attribute '__dict__' of 'zhcptStudent' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStudent' objects>, '__doc__': None}

修改

zhcptStudent.school = '珠海城市職業技術學院'
print(zhcptStudent.school)

運行結果:
珠海城市職業技術學院

初始化方法

首先先定義一個zhcptStudent類

class zhcptStudent:
    school = 'zhcpt'  # 相同的特征
    def learn(self):  # 相同的屬性
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')

stu1 = zhcptStudent()
stu2 = zhcptStudent()
stu1.learn()
stu2.eat()

# 運行結果是
----------run-----------
is learning
is eatting

上面說過,類是具有一系列對象相似的技能和屬性的結合體,對象特征與技能的結合體

那麼,實例化的對象,總有不同的地方,比如李坦克是男的,而張小麗是女的,所以我們需要為對象定製對象自己獨有的特征:

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

stu1 = Student()  # TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'sex'

這個時候就會報錯,提示缺少三個參數,但是我們卻沒有調用__init__方法,為什麼呢?因為python會自動調用,什麼時候會調用呢?創建對象、調用類、實例化的時候就會調用。

stu1 = Student('李坦克',18,'女')

那麼這個時候,就相當於把 ('李坦克','女'18) 三個參數傳遞進去了,即
        self.Name = '李坦克'
        self.Age = 18
        self.Sex = '女'

加上__init__方法後實例化的步驟:

​ 1.先產生一個空對象

​ 2.觸發Student.init(stu1,'李坦克',18,'女')

為什麼觸發就會把參數傳遞進去呢?

print(Student.__init__)

結果為:
<function Student.__init__ at 0x000001CFC9AE0C80>  # 原來__init__方法是一個函數,那麼函數就必須要傳入參數

類的操作

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

查找

stu1 = Student('張鐵牛',22,'男')
print(stu1.Name)
print(stu1.Age)
print(stu1.Sex)

# 運行結果為:
張鐵牛
22

stu1 = Student('張鐵牛',22,'男')
stu1.Name = '李鐵蛋'
print(stu1.Name)

# 運行結果為:
李鐵蛋

刪除

stu1 = Student('張鐵牛',22,'男')
del stu1.Name
print(stu1.__dict__)   # 查看對象的名稱空間

# 運行結果如下:
{'Age': 22, 'Sex': '男'}

增加

stu1 = Student('張鐵牛',22,'男')
stu1.class_name = 'python開發'
print(stu1.__dict__)

# 運行結果如下:
{'Name': '張鐵牛', 'Age': 22, 'Sex': '男', 'class_name': 'python開發'}

補充說明:

  • 站的角度不同,定義出的類是截然不同的
  • 現實中的類並不完全等於程式中的類,比如現實中的公司類,在程式中有時需要拆分成部門類、業務類
  • 有時為了編程需求,程式中也可能會定義出現實中不存在的類,比如策略類,現實中並不存在,但是在程式中卻是一個很常見的事

屬性查找與綁定方法

類有兩種屬性:數據屬性和函數屬性

1、類的數據屬性是所有對象共用的

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name  # 就相當於往類的名稱空間添加一個名字,是stu1的名稱空間
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

stu1 = Student('張全蛋',18,'男')  # 都有著相同的數據屬性,school = 'zhcpt'
stu2 = Student('王小麗',16,'女')
stu3 = Student('李黑',23,'男')

他們三個對象都定製了私有的特征:

print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)

# 運行結果如下:
{'Name': '張全蛋', 'Age': 18, 'Sex': '男'}
{'Name': '王小麗', 'Age': 16, 'Sex': '女'}
{'Name': '李黑', 'Age': 23, 'Sex': '男'}

訪問類中的數據屬性:是所有對象共有的

print(Student.school,id(Student.school))
print(stu1.school,id(stu1.school))
print(stu2.school,id(stu2.school))
print(stu3.school,id(stu3.school))

# 運行結果如下:
zhcpt 2347297903872
zhcpt 2347297903872
zhcpt 2347297903872
zhcpt 2347297903872

2、類的函數屬性是綁定給對象使用的,稱為對象的綁定方法

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name  # 就相當於往類的名稱空間添加一個名字,是stu1的名稱空間
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('%s  is learning',self.Name)
    def eat(self):
        print('%s  is eatting',self.Name)

stu1 = Student('張全蛋',18,'男')  # 都有著相同的數據屬性,school = 'zhcpt'
stu2 = Student('王小麗',16,'女')
stu3 = Student('李黑',23,'男')

訪問類中的函數屬性:是綁定給對象使用的,綁定到不同的對象是不同的綁定方法,對象調用綁定方法,就會把對象本身當作第一個參數傳遞給self

# 綁定方法,類的函數的記憶體地址,和對象的函數記憶體地址不一樣
print(stu1.learn)  # <bound method Student.learn of <__main__.Student object at 0x0000027BFF0680B8>>
# 對象訪問類中的函數屬性,則將本身作為第一個參數傳遞給self
print(stu1.learn())

# 運行結果
張全蛋  is learning

綁定方法的意思就是調用的都是同一種功能,但是大家執行的都是各自不同的方法

stu1.learn()
stu2.learn()
stu3.learn()

# 運行結果如下:
張全蛋  is learning
王小麗  is learning
李黑  is learning

類中定義的函數屬性,沒有任何處理的話,不是給類用的,實際上是綁定給對象使用的,誰來調用就是誰在使用這個功能

類即類型

python中一起都是對象,且python3中類與類型是一個概念,類型就是類


# 類型就是類
In [1]: print(list)

<class 'list'>

# 實例化3個對象
In [2]: l1 = list()

In [3]: l2 = list()

In [4]: l3 = list()

# 每個對象的綁定方法,都具有著相同的功能,但是記憶體地址不同
In [5]: print(l1.append)
<built-in method append of list object at 0x7ff344053e88>

In [6]: print(l2.append)
<built-in method append of list object at 0x7ff344035fc8>

In [7]: print(l3.append)
<built-in method append of list object at 0x7ff34431c5c8>

# 操作綁定方法l1.append(3),就是往l1里添加3,絕不會把3添加到l2或l3中
In [8]: l1.append(3)

In [9]: l1
Out[9]: [3]

In [10]: l2
Out[10]: []

In [11]: l3
Out[11]: []

# 調用類list.append(l3,111),實際上相當於:l3.append(111)
In [14]: list.append(l3,111)

In [15]: l3
Out[15]: [111]

從代碼級別看面向對象

1、在沒有學習類這個概念的時候,數據和功能是分開的

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

#每次調用都需要重覆傳入一堆參數
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存儲過程的名字')

2、我們就想到瞭解決方法是,把這些變數定義為全局變數

HOST=127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')
exc2(HOST,PORT,DB,CHARSET,'存儲過程的名字')

3、但是2的解決方法也是有問題的,按照2的思路,我們將會定義一大堆全局變數,這些全局變數並沒有做任何區分,即能夠被所有功能使用,然而事實上只有HOST,PORT,DB,CHARSET是給exc1和exc2這兩個功能用的。言外之意:我們必須找出一種能夠將數據與操作數據的方法組合到一起的解決方法,這就是我們說的類了

class MySQLHandler:
    def __init__(self,host,port,db,charset='utf8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(self.host,self.port,self.db,self.charset)
    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,sql):
        return self.conn.call_proc(sql)


obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存儲過程的名字')

總結使用類可以:將數據和專門操作該數據的功能整合到一起

可擴展性高

定義類並產生3個對象

class Chinese:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')

如果我們新增一個類屬性,將會立馬反應給所有對象,而對象卻無需修改

class Chinese:
    country='China'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def tell_info(self):
        info='''
        國籍:%s
        姓名:%s
        年齡:%s
        性別:%s
        ''' %(self.country,self.name,self.age,self.sex)
        print(info)


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')

print(p1.country)
p1.tell_info()

小節練習

編寫一個學生類,產生一堆學生對象
    要求:有一個計數器,統計總共實例化了多少對象
class Student:
    def __init__(self,name,sex,age):

        self.Name = name
        self.Sex = sex
        self.Age = age
        Student.count += 1

stu1 = Student('小明','男',14)
stu2 = Student('老王','男',38)
stu3 = Student('小麗','女',18)

這時候我們要考慮一個問題,對象的屬性是對象自己的, 所以....類的屬性是大家共有的

class Student:
    count = 0
    def __init__(self,name,sex,age):

        self.Name = name
        self.Sex = sex
        self.Age = age
        Student.count += 1

stu1 = Student('小明','男',14)
stu2 = Student('老王','男',38)
stu3 = Student('小麗','女',18)
print(Student.count)

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

-Advertisement-
Play Games
更多相關文章
  • 1 void vBubbleSort(int arr[], int len){ 2 int i, j, temp; 3 for (j = 0; j arr[i + 1]){ //交換兩個數 6 temp = arr[i]; 7 arr[i] = arr[i + 1]; 8 ... ...
  • nginx反向代理與正向代理 1 正向代理 3 正反向代理的區別 4 nginx的正向代理 5 nginx的反向代理配置 參考文章 : https://blog.csdn.net/hiyun9/article/details/51602428 非常感謝 ...
  • 一.變數 1. 首先我們要做的就是申明一個變數例如: name="xiaohua" name是我們的變數名,xiaohua是我們的變數值 變數時我們臨時儲存和調用 對於數字我們直接是:age=24 請註意,在使用變數前,需要對其賦值,不代表任何值得變數沒有意義。 下麵大家看一下麵這張圖片,想一下a, ...
  • "官方文檔 1.11" 配置 簡易文本郵件 連接一次郵件伺服器發送多份不同的郵件 和 發送多媒體郵件 發送html模板郵件 ...
  • 作者: "zyl910" 一、緣由 在項目開發時,因為運行環境的不同,導致有時得分別為不同的環境,切換配置參數打不同war包。但手工切換配置文件的話,不僅費時費力,而且容易出錯。 有些打包工具支持配置切換。這樣我們只要配好有那幾組參數,然後便可分別打war包了。但該辦法還是存在多個war文件易搞錯的 ...
  • 一般地,我們稱C++類聲明中的“函數原型”為介面,它只是提供給了用戶如何使用的具體細節,而隱藏了具體的代碼;類似地,我們稱類的成員函數的具體的代碼為實現。 ...
  • 一、Spring簡述 Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架,Spring致力於提供一種方法管理你的業務對象,Spring的主要目的是使JavaEE易用和促進好編程習慣,Spring致力於J2EE應用的各層的解決方案,而不是僅僅專註於某一層的方案,Sp ...
  • 起因:SpringBoot我是越用越喜歡,但當SpringBoot出了問題的時候,我卻無從下手,因為封裝實在是太高度化了。然後之前有一個需求,使用SpringBoot提供的StringRedisTemplate,我想定製裡面幾個屬性。如下麵代碼。 但我每次使用都是直接autowire註入進去的,然後 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...