主頁 > 後端開發 > Python_迭代器和生成器

Python_迭代器和生成器

2020-10-28 06:15:08 後端開發

楔子

假如我現在有一個串列l=['a','b','c','d','e'],我想取串列中的內容,有幾種方式?

首先,我可以通過索引取值l[0],其次我們是不是還可以用for回圈來取值呀?

你有沒有仔細思考過,用索引取值和for回圈取值是有著微妙區別的,

如果用索引取值,你可以取到任意位置的值,前提是你要知道這個值在什么位置,

如果用for回圈來取值,我們把每一個值都取到,不需要關心每一個值的位置,因為只能順序的取值,并不能跳過任何一個直接去取其他位置的值,

但你有沒有想過,我們為什么可以使用for回圈來取值?

for回圈內部是怎么作業的呢?

迭代器

python中的for回圈

要了解python中的for回圈是怎么回事兒,咱們還是要從代碼的角度出發,

首先,我們對一個串列進行for回圈,

for i in [1,2,3,4]:  
    print(i)

上面這段代碼肯定是沒有問題的,但是我們換一種情況,來回圈一個數字1234試試

for i in 1234
    print(i) 

結果:
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    for i in 1234:
TypeError: 'int' object is not iterable

看,報錯了!報了什么錯呢?“TypeError: 'int' object is not iterable”,說int型別不是一個iterable,那這個iterable是個啥?

假如你不知道什么是iterable,我們可以翻翻詞典,首先得到一個中文的解釋,盡管翻譯過來了你可能也不知道,但是沒關系,我會帶著你一步一步來分析,

迭代和可迭代協議

什么叫迭代

現在,我們已經獲得了一個新線索,有一個叫做“可迭代的”概念

首先,我們從報錯來分析,好像之所以1234不可以for回圈,是因為它不可迭代,那么如果“可迭代”,就應該可以被for回圈了,

這個我們知道呀,字串、串列、元組、字典、集合都可以被for回圈,說明他們都是可迭代的

我們怎么來證明這一點呢?

from collections import Iterable
                             
l = [1,2,3,4]                
t = (1,2,3,4)                
d = {1:2,3:4}                
s = {1,2,3,4}                
                             
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))

結合我們使用for回圈取值的現象,再從字面上理解一下,其實迭代就是我們剛剛說的,可以將某個資料集內的資料“一個挨著一個的取出來”,就叫做迭代

可迭代協議

我們現在是從結果分析原因,能被for回圈的就是“可迭代的”,但是如果正著想,for怎么知道誰是可迭代的呢?

假如我們自己寫了一個資料型別,希望這個資料型別里的東西也可以使用for被一個一個的取出來,那我們就必須滿足for的要求,這個要求就叫做“協議”,

可以被迭代要滿足的要求就叫做可迭代協議,可迭代協議的定義非常簡單,就是內部實作了__iter__方法,

接下來我們就來驗證一下:

print(dir([1,2]))
print(dir((2,3)))
print(dir({1:2}))
print(dir({1,2}))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
結果

總結一下我們現在所知道的:可以被for回圈的都是可迭代的,要想可迭代,內部必須有一個__iter__方法,

接著分析,__iter__方法做了什么事情呢?

print([1,2].__iter__())

結果
<list_iterator object at 0x1024784a8>

執行了list([1,2])的__iter__方法,我們好像得到了一個list_iterator,現在我們又得到了一個新名詞——iterator,

iterator,這里給我們標出來了,是一個計算機中的專屬名詞,叫做迭代器,

迭代器協議

既什么叫“可迭代”之后,又一個歷史新難題,什么叫“迭代器”?

雖然我們不知道什么叫迭代器,但是我們現在已經有一個迭代器了,這個迭代器是一個串列的迭代器,

我們來看看這個串列的迭代器比起串列來說實作了哪些新方法,這樣就能揭開迭代器的神秘面紗了吧?

復制代碼
'''
dir([1,2].__iter__())是串列迭代器中實作的所有方法,dir([1,2])是串列中實作的所有方法,都是以串列的形式回傳給我們的,為了看的更清楚,我們分別把他們轉換成集合,
然后取差集, ''' #print(dir([1,2].__iter__())) #print(dir([1,2])) print(set(dir([1,2].__iter__()))-set(dir([1,2]))) 結果: {'__length_hint__', '__next__', '__setstate__'}
復制代碼

我們看到在串列迭代器中多了三個方法,那么這三個方法都分別做了什么事呢?

復制代碼
iter_l = [1,2,3,4,5,6].__iter__()
#獲取迭代器中元素的長度
print(iter_l.__length_hint__())
#根據索引值指定從哪里開始迭代
print('*',iter_l.__setstate__(4))
#一個一個的取值
print('**',iter_l.__next__())
print('***',iter_l.__next__())
復制代碼

這三個方法中,能讓我們一個一個取值的神奇方法是誰?

沒錯!就是__next__

在for回圈中,就是在內部呼叫了__next__方法才能取到一個一個的值,

那接下來我們就用迭代器的next方法來寫一個不依賴for的遍歷,

復制代碼
l = [1,2,3,4]
l_iter = l.__iter__()
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
復制代碼

這是一段會報錯的代碼,如果我們一直取next取到迭代器里已經沒有元素了,就會拋出一個例外StopIteration,告訴我們,串列中已經沒有有效的元素了,

這個時候,我們就要使用例外處理機制來把這個例外處理掉,

復制代碼
l = [1,2,3,4]
l_iter = l.__iter__()
while True:
    try:
        item = l_iter.__next__()
        print(item)
    except StopIteration:
        break
復制代碼

那現在我們就使用while回圈實作了原本for回圈做的事情,我們是從誰那兒獲取一個一個的值呀?是不是就是l_iter?好了,這個l_iter就是一個迭代器,

迭代器遵循迭代器協議:必須擁有__iter__方法和__next__方法,

還賬:next和iter方法

如此一來,關于迭代器和生成器的方法我們就還清了兩個,最后我們來看看range()是個啥,首先,它肯定是一個可迭代的物件,但是它是否是一個迭代器?我們來測驗一下

print('__next__' in dir(range(12)))  #查看'__next__'是不是在range()方法執行之后內部是否有__next__
print('__iter__' in dir(range(12)))  #查看'__next__'是不是在range()方法執行之后內部是否有__next__

from collections import Iterator
print(isinstance(range(100000000),Iterator))  #驗證range執行之后得到的結果不是一個迭代器

# range的回傳值是一個可迭代物件

為什么要有for回圈

基于上面講的串列這一大堆遍歷方式,聰明的你立馬看除了端倪,于是你不知死活大聲喊道,你這不逗我玩呢么,有了下標的訪問方式,我可以這樣遍歷一個串列啊

l=[1,2,3]

index=0
while index < len(l):
    print(l[index])
    index+=1

#要毛線for回圈,要毛線可迭代,要毛線迭代器

沒錯,序列型別字串,串列,元組都有下標,你用上述的方式訪問,perfect!但是你可曾想過非序列型別像字典,集合,檔案物件的感受,所以嘛,年輕人,for回圈就是基于迭代器協議提供了一個統一的可以遍歷所有物件的方法,即在遍歷之前,先呼叫物件的__iter__方法將其轉換成一個迭代器,然后使用迭代器協議去實作回圈訪問,這樣所有的物件就都可以通過for回圈來遍歷了,而且你看到的效果也確實如此,這就是無所不能的for回圈,覺悟吧,年輕人

生成器

初識生成器

我們知道的迭代器有兩種:一種是呼叫方法直接回傳的,一種是可迭代物件通過執行iter方法得到的,迭代器有的好處是可以節省記憶體,

如果在某些情況下,我們也需要節省記憶體,就只能自己寫,我們自己寫的這個能實作迭代器功能的東西就叫生成器,

Python中提供的生成器:

1.生成器函式:常規函式定義,但是,使用yield陳述句而不是return陳述句回傳結果,yield陳述句一次回傳一個結果,在每個結果中間,掛起函式的狀態,以便下次重它離開的地方繼續執行

2.生成器運算式:類似于串列推導,但是,生成器回傳按需產生結果的一個物件,而不是一次構建一個結果串列

生成器Generator:

  本質:迭代器(所以自帶了__iter__方法和__next__方法,不需要我們去實作)

  特點:惰性運算,開發者自定義

生成器函式

一個包含yield關鍵字的函式就是一個生成器函式,yield可以為我們從函式中回傳值,但是yield又不同于return,return的執行意味著程式的結束,呼叫生成器函式不會得到回傳的具體的值,而是得到一個可迭代的物件,每一次獲取這個可迭代物件的值,就能推動函式的執行,獲取新的回傳值,直到函式執行結束,

# 初識生成器一
import time def genrator_fun1(): a = 1 print('現在定義了a變數') yield a b = 2 print('現在又定義了b變數') yield b g1 = genrator_fun1() print('g1 : ',g1) #列印g1可以發現g1就是一個生成器 print('-'*20) #我是華麗的分割線 print(next(g1)) time.sleep(1) #sleep一秒看清執行程序 print(next(g1))

生成器有什么好處呢?就是不會一下子在記憶體中生成太多資料

假如我想讓工廠給學生做校服,生產2000000件衣服,我和工廠一說,工廠應該是先答應下來,然后再去生產,我可以一件一件的要,也可以根據學生一批一批的找工廠拿,
而不能是一說要生產2000000件衣服,工廠就先去做生產2000000件衣服,等回來做好了,學生都畢業了,,,

#初識生成器二

def produce():
    """生產衣服"""
    for i in range(2000000):
        yield "生產了第%s件衣服"%i

product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服
num = 0
for i in product_g:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

#到這里我們找工廠拿了8件衣服,我一共讓我的生產函式(也就是produce生成器函式)生產2000000件衣服,
#剩下的還有很多衣服,我們可以一直拿,也可以放著等想拿的時候再拿

更多應用

生成器監聽檔案輸入的例子

import time

def tail(filename):
    f = open(filename)
    f.seek(0, 2) #從檔案末尾算起
    while True:
        line = f.readline()  # 讀取檔案中新的文本行
        if not line:
            time.sleep(0.1)
            continue
        yield line

tail_g = tail('tmp')
for line in tail_g:
    print(line)

send

def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield2

g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello')   #send的效果和next一樣
print('***',ret)

#send 獲取下一個值的效果和next基本一致
#只是在獲取下一個值的時候,給上一yield的位置傳遞一個資料
#使用send的注意事項
    # 第一次使用生成器的時候 是用next獲取下一個值
    # 最后一個yield不能接受外部的值
def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total/count


g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))
計算移動平均值(1) 計算移動平均值(2)_預激協程的裝飾器

yield from

def gen1():
    for c in 'AB':
        yield c
    for i in range(3):
        yield i

print(list(gen1()))

def gen2():
    yield from 'AB'
    yield from range(3)

print(list(gen2()))

串列推導式和生成器運算式

#老男孩由于峰哥的強勢加盟很快走上了上市之路,alex思來想去決定下幾個雞蛋來報答峰哥

egg_list=['雞蛋%s' %i for i in range(10)] #串列決議

#峰哥瞅著alex下的一筐雞蛋,捂住了鼻子,說了句:哥,你還是給我只母雞吧,我自己回家下

laomuji=('雞蛋%s' %i for i in range(10))#生成器運算式
print(laomuji)
print(next(laomuji)) #next本質就是呼叫__next__
print(laomuji.__next__())
print(next(laomuji))

總結:

1.把串列決議的[]換成()得到的就是生成器運算式

2.串列決議與生成器運算式都是一種便利的編程方式,只不過生成器運算式更節省記憶體

3.Python不但使用迭代器協議,讓for回圈變得更加通用,大部分內置函式,也是使用迭代器協議訪問物件的,例如, sum函式是Python的內置函式,該函式使用迭代器協議訪問物件,而生成器實作了迭代器協議,所以,我們可以直接這樣計算一系列值的和:

sum(x ** 2 for x in range(4))

而不用多此一舉的先構造一個串列:

sum([x ** 2 for x in range(4)]) 

 

更多精彩請見——迭代器生成器專題:http://www.cnblogs.com/Eva-J/articles/7276796.html

本章小結

可迭代物件:

  擁有__iter__方法

  特點:惰性運算

  例如:range(),str,list,tuple,dict,set

迭代器Iterator:

  擁有__iter__方法和__next__方法

  例如:iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o

生成器Generator:

  本質:迭代器,所以擁有__iter__方法和__next__方法

  特點:惰性運算,開發者自定義

使用生成器的優點:

1.延遲計算,一次回傳一個結果,也就是說,它不會一次生成所有的結果,這對于大資料量處理,將會非常有用,

#串列決議
sum([i for i in range(100000000)])#記憶體占用大,機器容易卡死
 
#生成器運算式
sum(i for i in range(100000000))#幾乎不占記憶體

2.提高代碼可讀性

生成器相關的面試題

生成器在編程中發生了很多的作用,善用生成器可以幫助我們解決很多復雜的問題

除此之外,生成器也是面試題中的重點,在完成一些功能之外,人們也想出了很多魔性的面試題,
接下來我們就來看一看~

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)

print(list(g1))
print(list(g2))
def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()
for n in [1,10]:
    g=(add(n,i) for i in g)

print(list(g))
import os

def init(func):
    def wrapper(*args,**kwargs):
        g=func(*args,**kwargs)
        next(g)
        return g
    return wrapper

@init
def list_files(target):
    while 1:
        dir_to_search=yield
        for top_dir,dir,files in os.walk(dir_to_search):
            for file in files:
                target.send(os.path.join(top_dir,file))
@init
def opener(target):
    while 1:
        file=yield
        fn=open(file)
        target.send((file,fn))
@init
def cat(target):
    while 1:
        file,fn=yield
        for line in fn:
            target.send((file,line))

@init
def grep(pattern,target):
    while 1:
        file,line=yield
        if pattern in line:
            target.send(file)
@init
def printer():
    while 1:
        file=yield
        if file:
            print(file)

g=list_files(opener(cat(grep('python',printer()))))

g.send('/test1')

協程應用:grep -rl /dir

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/194765.html

標籤:Python

上一篇:Python_裝飾器函式

下一篇:HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out的解決方法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more