必知必會的8個Python列表技巧

原作者:Nik Piepenbreier

翻譯&內容補充:費弗里

原文地址:https://towardsdatascience.com/advanced-python-list-techniques-c6195fa699a3

  列表(List)是你使用Python過程中接觸最為頻繁的數據結構,也是功能最為強大的幾種數據結構之一。Python列表非常的萬能且蘊含着許多隱藏技巧,下面我們就來探索一些常用的列表技巧。

1 列表元素的過濾

1.1 filter()的使用

  filter()函數接受2個參數:1個函數對象以及1個可迭代的對象,接下來我們定義1個函數然後對1個列表進行過濾。

  首先我們創建1個列表,並且剔除掉小於等於3的元素:

圖1

  回顧一下發生了什麼:

  1. 我們定義了列表original_list
  2. 接着我們定義了一個接受數值型參數number的函數filter_three,當傳入的參數值大於3時會返回True,反之則會返回False
  3. 我們定義了filter對象filtered,其中filter()接受的第一個參數是函數對象,第二個參數是列表對象
  4. 最終我們將filter對象轉化為列表,最終得到經filter_three過濾后original_list內留下的元素。

1.2 使用列表推導式

  類似的,我們也可以利用列表推導式來過濾列表元素,作為一種生成和修改列表優雅的方式,列表推導式想必大家都比較熟悉了,下面是使用列表推導完成同樣任務的過程:

圖2

2 修改列表

2.1 map()的使用

  Python中內置的map()函數使得我們可以將某個函數應用到可迭代對象內每一個元素之上。

  比方說我們想獲取到一個列表對象中每一個元素的平方,就可以使用到map()函數,就像下面的例子一樣:

圖3

  類似filter()的工作過程,下面我們來看看發生了什麼:

  1. 首先我們定義了列表original_list,以及接受數值型參數並返回其平方值的函數square()
  2. 接着我們定義了map對象squares,類似filter()map()接受的第一個參數是函數對象,第二個參數是列表對象
  3. 最終我們將map對象squares列表化,就得到了想要的結果

2.2 使用列表推導式

  同樣的我們也可以使用列表推導式完成同樣的任務:

圖4

3 利用zip()來組合列表

  有些情況下我們需要將兩個或以上數量的列表組合在一起,這類需求使用zip()來完成非常方便。

  zip()函數接收多個列表作為參數傳入,進而得到每個位置上一一對應的元素組合,就像下面的例子一樣:

圖5

4 顛倒列表

  Python中的列表是有序的數據結構,正因如此,列表中元素的順序很重要,有些時候我們需要翻轉列表中所有元素的順序,可以通過Python中的切片操作,用::-1來快捷地實現:

圖6

5 檢查列表中元素的存在情況

  有些情況下我們想要檢查列表中是否存在某個元素,這種時候就可以使用到Python中的in運算符,譬如說我們有一個記錄了所有比賽獲勝隊伍名稱的列表,當我們想查詢某個隊名是否已獲勝時,可以像下面的例子一樣:

圖7

6 找出列表中出現次數最多的元素

  有些情況下我們想要找出列表中出現次數最多的元素,譬如對記錄若干次拋硬幣結果的列表,找出哪一種結果出現次數最多,就可以參考下面的例子:

圖8

7 展平嵌套列表

  有些情況下我們會遇到一些嵌套的列表,其每個元素又是各自不同的列表,這種時候我們就可以利用列表推導式來把這種嵌套列表展平,如下面2層嵌套的例子:

圖9

額外補充

  原作者這裏只考慮到兩層嵌套的列表,如果是更多層嵌套,就需要有多少層寫多少for循環,比較麻煩,其實還有一種更好的方法,我們可以使用pip install dm-tree來安裝tree這個專門用於展平嵌套結構的庫,可以展平任意層嵌套列表,使用例子如下:

圖10

8 檢查唯一性

  如果你想要查看列表中的值是否都是唯一值,可以使用Python中的set數據結構的特點,譬如下面的例子:

圖11

  以上就是本文的全部內容,如有疑問歡迎在評論區討論~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

一分鐘開始持續集成之旅系列之:C 語言 + Makefile

作者:CODING – 朱增輝

前言

make 工具非常強大,配合 makefile 文件可以實現軟件的自動化構建,但是執行 make 命令依然需要經歷手動輸入執行、等待編譯完成、將目標文件轉移到合適位置等過程,我們真正關心的是最終的輸出,卻在這些中間過程上浪費了很多時間。利用 CODING 持續集成功能可以實現自動觸發構建,構建全程自動化,無須分心看護,節省時間。

本文通過一個 C 語言 + Makefile Demo 項目講解如何使用 CODING 持續集成功能創建構建計劃,自動觸發構建,以及如何將生成的目標文件發布到 CODING generic 製品庫。

準備工作

環境

本文涉及到以下工具,請確認已存在,或者根據鏈接的文檔進行安裝。

  • git
  • make
  • gcc

另外,您還需準備一個 CODING 項目。

代碼

我已經準備了一份簡單的示例代碼,使用 make 工具構建 Hello-world 程序。

// hello.c
#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

您可以通過下面的命令克隆到本地。

git clone https://e.coding.net/coding-public/demo-c-make.git

倉庫中還包含了一個 makefile 文件,定義了簡單的規則來完成軟件構建。

all: hello

hello: hello.o
	gcc -o hello hello.o

hello.o: hello.c
	gcc -c hello.c

clean:
	rm -rf hello.o hello

您可以在本地執行 make 命令以驗證構建正常。

下面我們正式開始通過一個 Demo 演示 CODING 平台持續集成功能的使用。

步驟一 創建製品庫

為了方便隨時使用構建出來的目標文件,我們將構建物存儲到 CODING 平台製品庫,因此需要先創建合適的製品倉庫,這裏創建 generic 倉庫比較合適。

從左側導航欄打開製品庫

單擊新建倉庫,選擇 generic 類型,按照提示指定倉庫名稱,這裏倉庫名取為 generic。

步驟二 創建並配置構建計劃

從左側導航欄打開持續集成 --> 構建計劃頁面,點擊新建構建計劃配置創建並配置新的構建計劃。在彈出的頁面中,輸入構建計劃名稱,選擇代碼倉庫,配置來源指的的該構建計劃的構建腳本存放位置,對於簡單的、變動不頻繁的腳本可以使用靜態配置的選項,否則更推薦使用代碼倉庫中的腳本,這樣更加靈活,方便管理

點擊使用模板,可根據自己需要選擇合適模板,這裏選擇 簡易模板

保存構建計劃后,系統會自動將構建模板對應的 Jenkinsfile 推送到倉庫,默認為 master 分支。

步驟三 編寫構建腳本

構建腳本定義構建過程的具體步驟,是構建計劃的核心部分。CODING 平台提供了圖形化編輯器方便您快速編寫構建腳本。

CODING 持續集成底層基於開源 CI/CD 軟件領導者 Jenkins 實現,完全兼容 Jenkins pipeline 構建腳本語法,根據 Jenkins 官方提供的腳本編寫指南,可以實現更複雜的構建任務,CODING 也提供了文本編輯器方便您在線編輯。

代碼倉庫中已包含一個簡單的構建腳本(Jenkisnfile),您可以按照自己的想法參考編寫。

// Jenkinsfile
pipeline {
  agent any
  stages {
    stage('檢出') {
      steps {
        checkout([
          $class: 'GitSCM',
          branches: [[name: env.GIT_BUILD_REF]],
          userRemoteConfigs: [[
            url: env.GIT_REPO_URL,
            credentialsId: env.CREDENTIALS_ID
          ]]])
        }
      }
      stage('構建') {
        steps {
          echo '構建中...'
          sh 'make'
          echo '構建完成.'
        }
      }
      stage('發布') {
        steps {
          echo '發布中...'
          codingArtifactsGeneric(
            files: 'hello',
            repoName: "${env.GENERIC_REPO_NAME}",
            version: "${env.GIT_COMMIT}",
          )
          echo '發布完成'
        }
      }
    }
  }
}

構建腳本中的大部分內容都比較容易理解,稍顯陌生的是 codingArtifactsGeneric 步驟,這是 CODING 官方提供的插件,方便上傳到 CODING generic 製品庫。該插件通過環境變量 GENERIC_REPO_NAME 獲取倉庫名,因此需要配置構建計劃設置該變量值。

步驟四 配置觸發構建規則

CODING 持續功能支持多種觸發方式包括代碼源觸發、定時觸發、API 觸發及手動觸發,這幾種觸發方式可以同時配置互不衝突,其中代碼源觸發又可配置為推送到指定分支或標籤觸發,觸發方式多樣,可滿足絕大部分場景需要。

如前言中所說,我們希望把更多的精力放在源代碼上,盡量減少構建所帶來的干擾,因此這裏必不可少的是配置通過代碼源觸發,通過配置如下正則表達式,可以在推送代碼到匹配的分支名時自動觸發構建。

^refs/(heads/(release|release-.*|build-.*|feat-.*|fix-.*|test-.*|mr/.*))

步驟五 執行構建

執行構建最簡單的方式是手動觸發構建,選中想要構建的構建計劃,單擊立即構建會彈出配置窗口,在這裏可以配置此次構建使用的參數,單擊確定即可開始構建。

按照步驟四的配置,我們的構建計劃也支持推送的匹配分支觸發構建,您可以執行如下命令創建新分支並推送到遠端倉庫,即可觸發構建。

git checkout -b build-ci-test
git push origin HEAD

觸發后,構建會自動執行,您可以繼續做其他事情。

步驟六 下載目標文件

步驟三中定義的構建腳本會將構建出的目標文件發布到 CODING 製品庫,如果我們想要在本地使用也是很方便下載的。在製品倉庫中單擊文件名即可看到指引頁,裏面給出了對文件不同操作的命令。

總結

本文通過一個 C 語言 + makefile 的 Demo 項目講解了 CODING 持續集成、製品庫的簡單使用。藉由 CODING 平台的這些功能,我們像是雇了一個永不會累的助手,承擔了耗時的構建工作,從而節省了時間,提高了效率。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

基於雲服務的個人網站架構設計

本文介紹如何基於各種雲服務優雅且低成本地搭建個人網站,涉及的雲產品有雲服務器、SSL、企業郵箱、對象存儲、CDN、雲函數、API網關、雲監控等。

概述

如今雲服務提供商們提供了大量涵蓋計算、網絡、存儲等方面的雲服務,其中一些雲產品功能強大,如果能善加利用可以大幅降低開發和運維的成本。下面以基於騰訊雲搭建的個人網站為例,對網站整體的架構進行介紹。

網站目前的主要功能是個人博客,後續可以擴展如個人網盤等其他應用。當前架構圖如下:

一、基礎設施

1.雲服務器CVM

雲服務器使用的是CVM,1核2G,下行帶寬1Mbps,這個配置用來搭建起步階段的個人博客是完全夠用了,購買學生機或者在活動時購買價格也比較便宜。

有了服務器資源就可以開始博客搭建,我選的博客系統是極簡主義的Typecho,安裝過程可以參考這篇博文,主要是在服務器上安裝nginx、mysql、php以及typecho的源碼。

2.域名

註冊 – 備案 – 解析

服務器創建后同時會分配一個公網ip,但是為了便於分享和傳播,建議進行域名註冊。註冊后需要進行備案,現在的備案流程也已經簡化為在小程序上操作,省去了原有的幕布拍照環節,前後大概1-2周時間就可以完成備案。之後在控制台進行域名解析,即綁定域名和服務器ip,注意對帶或不帶www前綴的域名都要進行解析,完成解析后就可以在瀏覽器通過域名來訪問網頁了。

主域名的確定

為了便於SEO,建議根據個人喜好確定一個主域名,因為搜索引擎對於帶www和不帶www前綴的地址是當成兩個網站分開計算權重的。國內網站一般帶www,而國外網站(如github、stackoverflow、leetcode)等是不帶www的。我這裡是選擇不帶www的地址(zhayujie.com),並在nginx中配置對帶www的訪問301重定向到不帶www上,以集中權重。

企業郵箱

擁有域名后,還可以註冊以自己域名為後綴的企業郵箱,基礎版免費使用且賬號數量無上限,再也不用擔心郵箱號不夠用了(如微信公眾平台註冊),郵箱格式類似於 zyj@zhayujie.com

3.全站HTTPS

為了網站安全以及利於SEO,建議支持https協議訪問網站。可以申請免費的SSL證書,將證書和私鑰放置到服務器,並在nginx中開啟並配置SSL。同樣為了避免分散權重,可以把http訪問的請求301重定向到https上。以我的網站為例,帶不帶www以及是否使用https都會統一訪問https://zhayujie.com/。

二、基於COS和CDN的圖床

1.對象存儲COS

由於服務器下行帶寬有限,如果圖片存儲於我們自己的服務器,出現併發訪問時可能導致帶寬超限,訪問速度下降。所以可以把圖片存儲到 COS(Cloud Object Storage)中,搭建自己的圖床,這樣當博客同步到其他博客平台時,也便於對圖片資源進行統一管理。

COS的使用比較簡單,類似於網盤,在存儲桶中可以建立樹狀目錄結構,每個存儲桶(bucket)會分配一個公網域名,其下的文件通過https://{bucket}/{dir}/{filename}的形式進行訪問。但在博客中直接使用該鏈接是不妥的,因為一旦我們遷移到其他雲服務商或者切換其他的存儲方式了,原有的鏈接就失效了,一一修改成本太高。好在cos支持配置自定義域名,可以通過類似http://{domain}/{dir}/{filename}的地址進行訪問。

2.內容分髮網絡CDN

COS的自定義源站域名不支持https訪問,為了不影響我們的全站https,並且同時提升訪問速度和減少流量成本,可以配合CDN服務,開啟自定義CDN加速域名,具體步驟見文檔。

可以選取一個子域名作為cdn自定義域名,添加CNAME解析,這樣通過自定義域名會首先訪問cdn邊緣服務器,如果未命中則回源到cos。例如上面的圖片我配置的地址是https://blog.cos.zhayujie.com/web/blog-cloud-arch.jpg。

三、基於Serverless的消息服務

1.雲函數SCF

在博客開發過程中會遇到一些發送消息的功能,比如讀者回復文章時給筆者發送通知,筆者回複評論時給讀者發送通知,博文發布時給訂閱的讀者發送通知等等。這種消息通知的功能是很適合單獨拆分出來形成一個消息服務的,如果寫在博客源碼中則復用性差(網站下其他應用要發送消息時需要重寫),而單獨部署服務又會增加運維的成本(如果服務掛掉怎麼辦),這時候可以考慮serverless(無服務器)的架構,僅將我們的核心代碼片段託管給雲服務商。

騰訊雲提供了雲函數SCF(Serverless Cloud Function),是一種FaaS技術。對於消息通知這種異步、無狀態的功能,很適合使用雲函數編寫,比如接收到請求後向指定接收人發送一封郵件。

2.API網關

雲函數的觸發方式有多種,最常用的有定時任務和API網關。由於消息通知是通過事件觸發而不是定時觸發,所以選擇API網關,創建了觸發器后便可從公網直接訪問該函數,與Nginx反向代理的作用類似。

API網關的域名是隨機生成的,不利於對未來變化的擴展,故同樣綁定自定義域名,使用https://{domain}/{function}形式的地址觸發函數。例如我的郵件發送函數地址配置為https://apigw.zhayujie.com/commentNotice,在業務代碼中只需向該地址發送POST請求即可觸發郵件投遞。

四、監控、快照和統計

1.監控告警

服務器的監控和告警同樣很重要,有助於我們及時發現並排查問題。監控部分一般直接在控制台的 雲服務器 – 實例 – 監控 中進行查看,有對不同時間周期和時間粒度下的CPU、內存、帶寬、磁盤等的詳細數據。

告警部分則在雲監控中配置,可以配置多種報警策略如對cpu、內存、帶寬等指標超出閾值後進行告警,以及一些機器故障事件(如ping不可達、機器重啟等)。對COS的報警同樣可以在此配置。告警渠道可以是微信、郵件和短信。

2.快照

為了防止服務器硬盤中的數據遭到攻擊或被誤刪,可以在 雲服務器 – 快照 控制台中設置進行快照備份,並且支持定期快照策略,設置每隔一段時間自動創建新的快照。

3.訪問統計

對網站的訪問情況進行統計分析有利於我們優化網站內容和體驗。對於訪問數據統計使用的是百度統計,使用埋點方式接入,可以查看每一個訪客的地域,來源,搜索詞,轉化等信息,統計訪問量趨勢。

對於搜索引擎工具使用的是百度站長工具,用於提交頁面收錄,查看索引量、抓取頻次等數據。

總結

以上就是一個功能齊全的個人博客的搭建過程,大致計算一下成本,雲服務器活動期購買一百一年,域名一般幾十塊一個,而COS、CDN、SCF等產品都有大量的免費額度,且在建站初期流量費用同樣是微乎其微,所以總體算下來成本是極低的。個人開發者可以把個人網站當做一個產品來做,思考如何利用好公有雲的各種雲產品資源來提升用戶體驗,提高開發效率,降低運維成本。

原文鏈接:https://zhayujie.com/blog-cloud-arch.html

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

虹軟人臉識別——官方 Qt Demo 移植到 Linux

一、前言

最近需要在 Linux 平台下開發一個人臉識別相關的應用,用到了虹軟的人臉識別 SDK。之前在 Windows 平台用過,感覺不錯,SDK 裏面還帶了 Demo 可以快速看到效果。打開 Linux 版本的 SDK 裏面沒有發現 Demo,於是想着把 Windows 的 Demo 移植到 Linux。這篇文章記錄了移植的過程,Linux 用的是 Ubuntu 20.04(使用虛擬機 VMware Workstation 15 Player)。

二、配置依賴

2.1 ArcFace SDK

到虹軟官網下載人臉識別 SDK 3.1 Linux 增值版本 解壓到合適的目錄,並從官網獲取 APP_ID、SDK_KEY 和 ACTIVE_KEY,用於寫到配置文件用來激活 SDK。

2.2 OpenCV

到 OpenCV 官網下載源碼,我用的版本是 3.4.9。可以按照官網的教程 Installation in Linux 自行編譯,我參考官網教程使用下面的這些命令在 GCC 9.3.0(Ubuntu 20.04 自帶的編譯器) 上編譯成功。

sudo apt update
sudo apt install build-essential
sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
cd <OpenCV 源碼目錄>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<自定義目錄> ..
make -j3    # 可以使用核心數 - 1 個線程來編譯
sudo make install

2.3 Qt

Qt 使用的是 5.14.2 版本。

三、項目文件

3.1 .pro 文件

原 Windows Demo 使用的是 Visual Studio 2015,在 Linux 下我這裏用到了 Qt Creator 進行開發,因此需要編寫 .pro 文件,包括以下幾個方面:

  • 用到的 Qt 模塊
  • 編譯出來的程序名
  • 用到的頭文件、源文件和資源文件
  • 依賴庫的頭文件及庫名

更具體的內容查看文末提供的源碼。

3.2 文件編碼

原源碼文件使用的是 GBK 編碼,需要轉換為 UTF-8 編碼。將下面的命令保存到 convert.sh 文件中並用 chmod u+x convert.sh 賦予可執行權限。

#!/bin/bash

for i in "$@"; do
    desc=$(file "$i")
    if $(echo $desc | grep -i "UTF-8 Unicode" > /dev/null); then
        if $(echo $desc | grep -i "(with BOM)" > /dev/null); then
            echo "Remove UTF-8 BOM: " $i
            sed -i "1s/^\xef\xbb\xbf//" "$i"
        fi
    elif $(echo $desc | grep -i "ISO-8859" > /dev/null); then
        echo     "GBK --> UTF-8   : " $i
        temp=temp.txt
        iconv -f gbk -t utf-8 -o "$temp" "$i"
        mv "$temp" "$i"
    fi
done

在源碼根目錄下運行 find . -type f \( -name "*.h" -o -name "*.cpp" \) | xargs -I{} ./convert.sh "{}" 將所有的文件的編碼從 GBK 轉為 UTF-8,並去除現有 UTF-8 文件的 BOM 頭。

四、代碼修改

到這裏已經可以用 Qt Creator 打開項目了,但在代碼中還存在一些問題,一方面是原代碼使用了一些 Windows 平台特有的 API,一方面是有些代碼在 Linux 有兼容性問題。先去除 Windows 特有的依賴到編譯通過,再補充必要的依賴,最後解決兼容性問題。

4.1 修改報錯直至編譯通過

直接進行編譯,逐步解決編譯錯誤,通過下面的方式可以解決編譯錯誤:

  • 刪除 Utils.cpp 中報錯的頭文件、GUID 宏、listDevices 函數的主體、UTF8_To_string 和 string_To_UTF8 函數。
  • 將所有包含的 qDebug 改為 QDebug
  • Sleep(milli) 改為 std::this_thread::sleep_for(std::chrono::milliseconds(milli))
  • 刪除 MSVC 的鏈接庫的編譯指令 #pragma comment ...
  • 將原來使用 OpenCV 2 的接口遷移到目前的 OpenCV 3。
    • IplImage 到 cv::Mat 的轉換由 cv::Mat mat(ipl, false) 改成 cv::Mat mat = cv::cvarrToMat(ipl)
    • cv::Mat 到 IplImage 的轉換由 IplImage(mat) 改成 cvIplImage(mat),在原來的代碼里 cv::Mat 轉為 IplImage 後有個取地址,對右值取地址是不安全的,需要用一個變量保存轉換后的值再對這個變量取地址。
    • 在調用 cvRectangle 時將 CV_RGB 改成 cvScalar
    • 使用 cv::cvtColor 需要額外包含頭文件 opencv2/imgproc.hpp
    • 使用 cv::VideoCapture 需要額外包含頭文件 opencv2/videoio.hpp
  • strcpy_s 改成 strncpy,僅有參數位置上的改變。
  • TRUE 改為 true,將 FALSE 改為 false

改了編譯錯誤后,忽略警告已經可以編譯通過了,接下來是補充剛才刪除的一些必要依賴及解決兼容性問題。

因為環境差異,可能出現錯誤的順序不一致,但基本上是上面提到的錯誤之一。

4.2 重新實現獲取攝像頭列表的函數

原 Windows Demo 使用了 Windows 特有的 dshow 來查找攝像頭,在這裏直接用 cv::VideoCapture 嘗試打開來獲取攝像頭的索引:

auto list = std::vector<int>();
for (auto i = 0; i != 10; ++i)
{
    auto cap = cv::VideoCapture(i);
    if (cap.isOpened()) { list.emplace_back(i); }
    cap.release();
}

Demo 可以只打開一個RGB攝像頭,也可以同時打開一個RGB攝像頭和一個IR攝像頭。原代碼保存獲取攝像頭的名稱,僅用來統計數量,具體打開哪個攝像頭是通過settings.ini文件來配置的。在改變探測攝像頭存在的數量的方式后,順帶改變了打開攝像頭的邏輯,僅一個攝像頭就認為是僅打開普通攝像頭。在settings.ini文件中配置兩種攝像頭的索引,如果索引為 -1,則自動把小的索引認為是普通攝像頭,大的索引認為是紅外攝像頭,如果和真實情況不一致可手動指定攝像頭索引。

settings.ini文件在後面運行 Demo 時會有更多的說明。

4.3 修復彈出文件選擇框失敗的兼容性問題

在 Ubuntu 20.04 下,Qt 的 QFileDialog::getOpenFileName 和 QFileDialog::getExistingDirectory 存在一些問題,在打開時會卡死界面,通過將最後一個參數設置為 QFileDialog::DontUseNativeDialog 可以解決這個問題。

五、運行 Demo

5.1 界面預覽

5.2 配置

  1. 配置文件已經隨源碼打包好了,在運行時需要移動到可執行程序所在的同級目錄下。
  2. 在配置文件中填入官網獲取的 APP_ID、SDK_KEY 和 ACTIVE_KEY。
  3. 編譯並運行。

六、源碼下載

基於官方windows Qt Demo修改后的源碼

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

python多線程+生產者和消費者模型+queue使用

多線程簡介

多線程:在一個進程內部,要同時干很多事情,就需要同時執行多個子任務,我們把進程內的這些子任務叫線程。
線程的內存空間是共享的,每個線程都共享同一個進程的資源
模塊:
1、_thread模塊 低級模塊(在python3里基本已棄用)
2、threading模塊 高級模塊 對_thread模塊進行了封裝

threading模塊使用

1.使用元組傳遞 threading.Thread(target=方法名,arg=(參數1,參數2...))
2.用字典傳遞 threading.Thread(target=方法名,kwargs={“參數名”:參數1,“參數名”:參數2,....})
3.混合使用元組和字典 threading.Thread(target=方法名,args=(參數1,參數2,...),kwargs={“參數名”:參數1,“參數名”:參數2,....})
4.查看線程數:
使用threading.enumerate()函數便可以看到當前線程的數量。
5.查看當前線程的名字:
使用threading.current_thread()可以看到當前線程的信息。
6.join([time]):等待至線程終止。這阻塞調用線程直至線程的join()方法被調用終止、正常退出或者拋出未處理的異常、或者是可選的超時發生。
7.isAlive():返回線程是否活動
8.getName(): 返回線程名
9.setNmae():設置線程名
10.後台線程(守護線程)
後台線程有一個特徵:如果所有的前台線程都死亡了,那麼後台線程也會自動死亡。
調用Thread對象的daemon屬性可將指定線程設置為後台線程。在下面程序可以看到程序里的線程被指定為後台線程,當所有前台程序都死亡了后,後台線程隨之死亡。當在整個虛擬機里只剩下後台線程時,程序就沒有繼續運行的必要了,所以程序也就退出了。

import threading
# 定義後台線程的線程執行體與普通線程沒有任何區別
def action(max):
    for i in range(max):
        print(threading.current_thread().name + "  " + str(i))
t = threading.Thread(target=action, args=(100,), name='後台線程')
# 將此線程設置成後台線程
# 也可在創建Thread對象時通過daemon參數將其設為後台線程
t.daemon = True
# 啟動後台線程
t.start()
for i in range(10):
    print(threading.current_thread().name + "  " + str(i))
# -----程序執行到此處,前台線程(主線程)結束------
# 後台線程也應該隨之結束

上面程序中的粗體字代碼先將t線程設置成後台線程,然後啟動該線程。本來該線程應該執行到i等於99時才會結束,但在運行程序時不難發現,該後台線程無法運行到99,因為當主線程也就是程序中唯一的前台線程運行結東后,程序會主動退出,所以後台線程也就被結東了。從上面的程序可以看出,主線程默認是前台線程,t線程默認也是前台線程。但並不是所有的線程默認都是前台線程,有些線程默認就是後台線程一一前台線程創建的子線程默認是前台線程,後台線程創建的子線程默認是後台線程
可見,創建後台線程有兩種方式。

  1. 主動將線程的 daemon屬性設置為True
  2. 後台線程啟動的線程默認是後台線程。

以下看一個簡單的多線程程序:

import threading
import time

def coding():
    for x in range(3):
        print('%s正在寫代碼' % x)
        time.sleep(1)

def drawing():
    for x in range(3):
        print('%s正在畫圖' % x)
        time.sleep(1)


def single_thread():
    coding()
    drawing()

def multi_thread():
    t1 = threading.Thread(target=coding)
    t2 = threading.Thread(target=drawing)

    t1.start()
    t2.start()

if __name__ == '__main__':
    multi_thread()

繼承自threading.Thread類:

為了讓線程代碼更好的封裝。可以使用threading模塊下的Thread類,繼承自這個類,然後實現run方法,線程就會自動運行run方法中的代碼。示例代碼如下:

import threading
import time

class CodingThread(threading.Thread):
    def run(self):
        for x in range(3):
            print('%s正在寫代碼' % threading.current_thread())
            time.sleep(1)

class DrawingThread(threading.Thread):
    def run(self):
        for x in range(3):
            print('%s正在畫圖' % threading.current_thread())
            time.sleep(1)

def multi_thread():
    t1 = CodingThread()
    t2 = DrawingThread()

    t1.start()
    t2.start()

if __name__ == '__main__':
    multi_thread()

start()和run()

start()
start()方法來啟動線程,真正實現了多線程運行。這時無需等待run方法體代碼執行完畢,可以直接繼續執行下面的代碼;通過調用Thread類的start()方法來啟動一個線程, 這時此線程是處於就緒狀態, 並沒有運行。 然後通過此Thread類調用方法run()來完成其運行操作的, 這裏方法run()稱為線程體,它包含了要執行的這個線程的內容, Run方法運行結束, 此線程終止。然後CPU再調度其它線程。run()
run()
run()方法當作普通方法的方式調用。程序還是要順序執行,要等待run方法體執行完畢后,才可繼續執行下面的代碼; 程序中只有主線程——這一個線程, 其程序執行路徑還是只有一條, 這樣就沒有達到寫線程的目的。
記住:多線程就是分時利用CPU,宏觀上讓所有線程一起執行 ,也叫併發。start() 和 run()的區別說明

start() : 它的作用是啟動一個新線程,新線程會執行相應的run()方法。start()不能被重複調用。
run() : run()就和普通的成員方法一樣,可以被重複調用。單獨調用run()的話,會在當前線程中執行run(),而並不會啟動新線程!

Lock版本生產者和消費者模型

生產者和消費者模式是多線程開發中經常見到的一種模式。生產者的線程專門用來生產一些數據,然後存放到一个中間的變量中。消費者再從這个中間的變量中取出數據進行消費。但是因為要使用中間變量,中間變量經常是一些全局變量,因此需要使用鎖來保證數據完整性。以下是使用threading.Lock鎖實現的“生產者與消費者模式”的一個例子:

import threading
import random
import time

gMoney = 1000
glo = threading.Lock()
gTotaltime = 10
gTime = 0
class Consumer(threading.Thread):
    def run(self):
        global gMoney
        global gTime
        while True:
            money = random.randint(100,1000)
            glo.acquire()
            if gMoney>= money:
                gMoney -= money
                print("{}消費了{}元,當前剩餘{}元".format(threading.current_thread(),money,gMoney))
            else:
                print("{}準備消費{}元,當前剩餘{}元,不足,不能消費".format(threading.current_thread(),money,gMoney))
            if gTime >= gTotaltime and money > gMoney:
                glo.release()
                break
            glo.release()
            time.sleep(0.7)

class Porducer(threading.Thread):
    def run(self):
        global gMoney
        global gTime
        while True:
            Money = random.randint(100,700)
            glo.acquire()
            if gTime == gTotaltime:
                glo.release()
                break
            gMoney += Money
            print("{}生產了{}元錢,剩餘{}元錢".format(threading.current_thread(),Money,gMoney))
            gTime += 1
            glo.release()
            time.sleep(0.5)

def main():
    for x in range(3):
       t1 = Porducer(name="生產者")
       t1.start()

    for i in range(5):
       t = Consumer(name="消費者")
       t.start()

if __name__ == '__main__':
    main()

queue線程安全隊列

在線程中,訪問一些全局變量,加鎖是一個經常的過程。如果你是想把一些數據存儲到某個隊列中,那麼Python內置了一個線程安全的模塊叫做queue模塊。Python中的queue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先進先出)隊列Queue,LIFO(后入先出)隊列LifoQueue。這些隊列都實現了鎖原語(可以理解為原子操作,即要麼不做,要麼都做完),能夠在多線程中直接使用。可以使用隊列來實現線程間的同步。相關的函數如下:

  1. 初始化Queue(maxsize):創建一個先進先出的隊列。
  2. qsize():返回隊列的大小。
  3. empty():判斷隊列是否為空。
  4. full():判斷隊列是否滿了。
  5. get():從隊列中取最後一個數據。
  6. put(item,block=Ture,timeout=None):將一個數據放到隊列中。如果隊列已滿,且block參數為Ture(阻塞),當前線程被阻塞,timeout指定阻塞時間,如果將timeout設置為None,則代表一直阻塞,直到有元素被放入隊列中:如果隊列已空,且block參數設置為False(不阻塞),則直接引發queue.Empty異常。
    下面就可以用queue來進行線程通信
import queue
import time
import threading

def set_value(q):
    index = 0
    while True:
        q.put(index)
        index += 1
        time.sleep(3)

def get_value(q):
    index = 0
    while True:
        print(q.get())
        time.sleep(0.5)
def main():
    q = queue.Queue(4)
    t1 = threading.Thread(target=set_value,args=[q])
    t2 = threading.Thread(target=get_value,args=[q])
    t1.start()
    t2.start()


if __name__ == '__main__':
    main()

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

綠色和平組織指雲頂集團涉燒芭 解決林火非僅印尼責任

轉載自達邦樹;文:烏舜安咿

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

住友化學將收購Nufarm南美農藥業務

摘錄自2019年9月30日日經中文網、大紀元、中國時報報導

日本的住友化學將開拓全球最大的農藥市場南美。住友化學將以11.9億澳元(約8.048億美元、800億日元)收購澳大利亞的農藥巨頭Nufarm的南美業務,銷售大豆的除草劑和農藥。住友化學完成收購後,南美的農藥業務將超過北美,成為該公司最大的農藥業務。

南美是世界上最大的農用化學品市場,隨著美中貿易展的激烈進行,南美的大豆和其它商品日益替代美國農產品,向中國出口。這是住友化學公司針對美中貿易戰影響作出的決定。

另外,澳洲旱災已威脅東澳地區作物生產,也打擊澳洲農業化學業者的獲利,Nufarm在美國的數座廠房也因洪水受創,Nufarm盼藉此籌資償債。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

奧地利大選 庫爾茨重返執政可能與綠黨合組政府

摘錄自2019年9月30日中央社報導

奧地利人民黨(OeVP)29日贏得國會大選,黨魁庫爾茨(Sebastian Kurz)30日將開始尋找聯合政府夥伴,這次可能轉向綠黨,但要成功並非易事。

拜選民關注氣候變遷之賜,綠黨此次大選交出創黨以來最佳表現,囊括約14%票數,和2017年連國會都進不了有天壤之別。

綠黨在提洛爾邦(Tyrol)和薩爾斯堡邦(Salzburg)都已與人民黨合作,一些人認為,可以把地方案例複製到全國層級。但在全國層級合作可能更困難一些。

綠黨全國領袖庫格勒(Werner Kogler)29日表示,人民黨需要「徹底改變」,他不只點出氣候變遷行動,也提及對抗貪瀆與貧窮。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

環保新招! 羅馬推回收塑膠瓶換免費車票

摘錄自2019年10月1日自由時報報導

義大利首都羅馬在三個車站裝設塑膠瓶回收機,讓乘客投入空瓶換取免費的地鐵票,以加強環保行動。

《路透》報導,羅馬垃圾回收率低且效率不佳,因此這項在7月啟動的回收計畫廣受歡迎,目前已回收了35萬個塑膠瓶。羅馬市公共交通公司(ATAC)表示,該計畫很快就會擴展到整個地鐵網路,並實施到2020年7月。

ATAC發言人表示,有些回收狂熱者不到20天內就收集了3500個塑膠瓶,價值175張車票。羅馬市民佩雷利(Claudio Perelli)說,「如果你花錢讓民眾參與(回收)活動,就算是沒有公民意識的人也會開始回收」。

參與計畫的乘客必須在手機上下載APP,應用程式會根據投入回收機的瓶子數量兌換所賺取的車票數量,一張效期100分鐘的車票「價格」為30個塑膠瓶。乘客無須再買紙本車票,直接使用APP上兌換到的電子車票刷卡進站。

報導指出,羅馬是歐盟第一個在地鐵再啟動該回收計畫的首都。北京和伊斯坦堡已採用類似的計畫。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

南極阿梅里冰棚裂出超巨大冰山 專家嚴密監控防船難

摘錄自2019年10月1日自由時報報導

南極洲阿梅里冰棚(Amery Ice Shelf)近日裂出該冰棚近50年最巨大的冰山,面積約1636平方公里,代號「D28」。

據《BBC》報導 ,南極洲的阿梅里冰棚(Amery Ice Shelf)近日裂出自1960年代以來最巨大的冰山。這塊冰山涵蓋面積約1636平方公里,略大於台灣新竹縣(1427平方公里),代號為「D28」。

報導指出,阿梅里冰棚是南極大陸第三大的冰架,也是南極洲東部關鍵的疏通渠道。事實上冰棚本身即為冰川流入海中所形成的海上浮冰層,裂出冰山是冰川維持平衡的手段。

因此,科學家早已預測到D28冰山將裂出,在此之前,阿梅里冰棚因為附近的衛星圖狀似「鬆動的牙」(Loose Tooth)而從2000年代起即備受關注。

專家估測D28冰山厚度約210公尺,含有3150億噸重的冰,專家必須時常監控這座冰山的動向,以防船難發生。

據悉,南極洲另一拉森C冰棚(Larsen C Ice Shelf)2017年曾產出更巨大的A68冰山,目前涵蓋面積是D28的三倍大。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!