全球首列!中國氫燃料電池有軌電車正式投入營運

  新華社報導,由中國中車唐山公司研製的世界首列商用型氫燃料混合動力100%低地板現代有軌電車,10月26日在河北唐山市唐胥鐵路載客營運,為全球氫燃料電池有軌電車首次商業營運,也是中國在新能源軌道交通領域實現重大突破。   經過4年多時間,中車唐山公司率先在全球首次突破了燃料電池/超級電容混合動力牽引和控制等一系列關鍵技術,研製的有軌電車完全取消受電弓和接觸網,實現污染物「零排放」和全程「無網」運行。   據悉,唐山工業旅遊線路採用氫燃料電池有軌電車,無需架設接觸網,不用沿途安裝第三軌和充電樁,完整保留了百年唐胥鐵路的原貌;列車採用世界最先進的100%低地板技術,車廂地板距軌道面僅35公分,無需月臺;最小轉彎半徑僅19公尺,可沿現有城市道路直接鋪設軌道,在地面行駛和停靠;線路運營全程13.84公里,有軌電車一次快速加氫只需15分鐘,可持續行駛40公里,最高運行時速70公里。   中車唐山公司表示,旗下氫燃料混合動力有軌電車係採用2動1拖3輛編組,設乘客座位66個,最大載客量336人,還可根據運營需求靈活增加編組和載客量;這種有軌電車不僅可最高速度持續運行,且在制動、停站時,由燃料電池和制動能量回收系統為超級電容和蓄電池充電,能量回收率達30%以上。   (本文內容由授權使用。首圖為中車唐山電車示意圖,來源:)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

Model 3瓶頸原因瞭了!Panasonic:電池產量料很快提升

  路透社報導,關於和美國電動車廠特斯拉(Tesla)共同營運的美國內華達州「Gigafactory」超級電池廠生產較計畫延遲一事,Panasonic社長津賀一宏於10月31日舉行的財報說明會上表示,Gigafactory產量預估很快就可以提升。   Gigafactory正在生產特斯拉新型電動車Model 3所需的電池。特斯拉10月2日宣布,因「生產上的阻礙」,故2017年第3季Model 3產量僅260台。特斯拉曾於8月2日公布2017年第2季財報時表示,第3季Model 3產量預估將超過1,500台。   津賀一宏指出,因Model 3初期生產稍微陷入苦戰,導致電池生產量高於車輛產量、造成陷入無法進一步生產電池的情況,因而現在是藉由改為生產非車輛用蓄電用電池來因應。   不過津賀一宏表示,因為現在已經很清楚了解Model 3產線瓶頸的原因,因此早晚可以提高車用電池產量。   Panasonic於10月31日盤後公布2017年度上半年(2017年4-9月)財報,因車用電池等車用相關事業銷售強勁,帶動合併營收較去年同期成長9.0%至3兆8,578億日圓,合併營益成長10.4%至1,965億日圓,合併純益萎縮10.9%至1,189億日圓、下滑主因為去年同期時因法人稅負擔減輕提振獲利大增。   Panasonic維持2017年度(2017年4月~2018年3月)財測預估不變;合併營收預估將年增6.2%至7.8兆日圓、合併營益將大增21.0%至3,350億日圓、合併純益將成長7.1%至1,600億日圓。   日經新聞報導,津賀一宏指出,未上修2017年度財測預估,主要是因為存在特斯拉等不確定因素。   日刊工業新聞1日報導,受特斯拉新型電動車生產延遲影響,Panasonic所訂下的2017年度特斯拉用車載電池銷售計畫恐推延。Panasonic目前將包含電池在內的車用產品2017年度營收目標設定為5,400億日圓、而該目標能否達成恐將受到特斯拉因素影響。   日經新聞10月26日報導,Panasonic計畫同步在日本、中國、美國等3地祭出增產投資,增產使用於EV等用途的鋰離子電池,預估3處據點的總投資額將達1,000億日圓的規模。在車用鋰離子電池中,Panasonic於乘用車市場的市佔率高達約4成、為全球最大廠。   其中,Panasonic和特斯拉共同營運的美國內華達州Gigafactory超級電池廠目前正同時進行第一期廠房建設和產線鋪設工程,不過因特斯拉急於進行增產,故已和Panasonic進行第二期工程的協商,而待第二期工程完工後,產能最高將增至1.5倍。   (本文內容由授權使用。首圖為Tesla Gigafactory,來源:Tesla)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

充電時間縮一半,本田傳2022年開賣多款超快速充電EV

日經新聞1日報導,本田(Honda)計畫在2022年開賣多款可進行「超快速充電」的電動車(EV)、其充電時間可縮短至現行的約一半水準。   現行EV在使用快速充電器時、充飽8成電力大多需花費30分鐘時間,而本田將研發能負荷在短時間內進行大量充電的電池產品,目標將充電時間縮減至15分鐘、且能跑240km。   據報導,本田目前油電混合車(HV)用電池是向Panasonic等廠商採購,而能進行超快速充電的電池研發夥伴將待今後討論決定。   本田目前規畫要在2019年以後於歐洲、日本開賣量產款EV。   (本文內容由授權使用。首圖為本田城市EV概念車,來源:)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※超省錢租車方案

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

網頁設計最專業,超強功能平台可客製化

OPEC:2040年OECD美洲市場EV市佔35%、中國逼近29%

  石油輸出國組織(OPEC)11月7日發布「世界石油展望(WOO)」報告指出,假設全球電動車(EV)年度銷售量在2040年達到8千萬輛(相當於每5台車就有3台是電動車),在電動車滲透率高於預期的情況下、全球石油日需求量可能會在2040年較基準預估值減少250萬桶至1.08億桶。據此推斷,全球石油需求將在2030年代下半階段持平於這個水位。   WOO指出,2016年全球上路的電動車據估計已升至200萬輛。目前已有6個國家的電動車市佔率(占整體轎車銷售量比重)突破1%、挪威電動車銷售量佔比更是高達29%。不過,電動車目前僅佔全球整體轎車車隊不到0.2%的比例。   WOO預估(見圖),2040年電動車在經濟合作暨發展組織(OECD)美洲新車市場的銷售佔比將高達35%左右、屆時中國電動車銷售佔比預估也將逼近29%,印度預估將達18%。   根據DNV GL首度發布的「能源轉型展望」報告,受電動車滲透率持續上揚的影響,石油供應將在2020~2028年期間轉趨持平、隨後大幅下降,2034年將遭天然氣超越。這份報告預估電動車、內燃引擎車將在2022年達到「成本平價」,預估到2033年全球半數輕型新車銷售量都將是電動車。   Thomson Reuters報導,嘉能可(Glencore)董事長Tony Hayward 5月受訪時表示,電動車的快速進步意味著石油需求可能會在2040年以前觸頂,深海鑽油、加拿大油砂等高成本原油生產商恐將先被淘汰出局,擁有生產成本優勢的OPEC相對較不受衝擊。Hayward曾任英國石油公司(BP Plc)執行長。   英國金融時報8月報導,瑞銀(UBS)預估2021年歐洲未經補貼的純電動車整體持有成本將與傳統內燃機汽車相當、中國也可望在2025年達到這項里程碑。   (本文內容由授權使用。首圖來源:public domain CC0)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

Tesla 將發表電動半掛卡車,產能遭質疑

  電動車製造商 Tesla 向媒體發出邀請函,定於 2017 年 11 月 16 日召開產品發表會,推出電動半掛卡車,儘管 Tesla 的無人駕駛部門還深陷與 Waymo 的訴訟中,也無礙 Elon Musk 進軍電動卡車市場的決心。   Tesla 的電動半掛卡車曾在測試中亮相,此次發表會將是這款產品首次對外公開展示,Tesla 的卡車業務是該公司在乘用車之外全新的產品線,之前並沒有太多信息曝光。Tesla 原定於 2017 年 10 月發表半掛卡車,由於 Tesla 投入了大量的資源和人力參與波多黎各的救災活動,導致新品發表一再延期。   德國汽車廠商 Daimler 已經推出了大載重的電動運輸卡車,單次充電的行駛里程約為 220 英里,據傳 Tesla 的半掛卡車單次充電的行駛里程大約為 200 英里到 300 英里,考慮到卡車載重所需的牽引力,電動卡車需要配置大容量的電池系統。   近日 Tesla 電池部門的主管 Jon Wagner 被爆已經從該公司離職,他在 2013 年 1 月加入 Tesla,參與了所有電動車的研發,還負責了 Tesla 的家用儲能裝置 Powerwall,核心高層的離職也讓外界對於 Tesla 的量產能力產生了更多質疑,Tesla 已經將 Model 3 量產目標延後 3 個月,制約產能的主要因素是內華達州的超級工廠電池模組生產線產能不足,導致不得不調整 Model 3 的部分生產環節。目前 Tesla 已經接收了超過 50 萬台 Model 3 訂單,但 2017 年第三季 Model 3 只生產了 260 台。   Tesla 執行長 Elon Musk 透露,在卡車的設計過程中與物流運輸公司展開合作,他們的參與有助於產品能夠更好地為物流產業服務,電動卡車新品主要是面向中短途路線設計,比如將貨物從城市中心區運輸到港口等,比使用燃油卡車運輸成本更低。此外 Tesla 半掛卡車還可能加入無人駕駛功能,該公司已經與美國車輛管理局就無人駕駛道路測試進行溝通。   Tesla 的無人駕駛領域還面臨的另一個挑戰就是與 Waymo 的官司,這起官司正是由於 Tesla 收購了無人駕駛卡車新創公司 Otto,該公司的創辦人是 Google 無人駕駛部門的前員工,離職時違規下載了許多機密商業文件,Alphabet 旗下無人駕駛公司 Waymo 認為 Tesla 竊取了商業機密並應用到無人駕駛的開發中,目前這起訴訟仍在庭審中。   (合作媒體:。首圖來源:public domain CC0)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

FB行銷專家,教你從零開始的技巧

倫敦一些地區要在路燈內安裝充電站,讓電動車充電更方便

 

 

隨著電動車逐漸興起,充電的問題變得越來越受到關注,當使用者在城市中開著電動車時,究竟該去哪裡尋找充電設施?Electrek 報導指出,倫敦一些地區似乎正試著透過在路燈柱內安裝充電站的計畫,來解決這個問題。

在充電的問題上,北歐國家似乎具有「先天」優勢,為了面臨嚴峻的冬季氣溫,他們原先在街道上就廣泛設有協助汽車引擎啟動的加熱器(block heater),因此也能夠運用同樣系統讓電動車能在街道上進行充電。

其他沒有這麼寒冷的地方就不同了,在沒有類似基礎設施的情況下,一些公司正在思考相關方案來解決這個問題;像是特斯拉就推出了城市專用的充電站,雖然因為功率低使得充電速度較慢,但也不失為市區內的一個選擇。

另一方面,位在倫敦的肯辛頓與切爾西區(RBKC)的行政當局則選擇了不同的做法,他們已經和能源供應商OVO Energy 和近期獲得西門子投資的德國充電公司ubitricity 簽約,要在都市中現有的燈柱內安裝充電站。

之所以做出這項決定,當地的交通委員會主席Cllr Gerard Hargreaves 表示,是因為居民的充電需求正隨著電動車持續增長,但多數人都無法在附近街道的停車處找到充電設施,讓電動車的充電變得難以進行。

Hargreaves 認為,透過在復古路燈內設置充電設施,駕駛人在住家附近就可以直接充電,倫敦的空氣汙染問題也得以緩解。「除此之外,在路燈內設置意味著不需要額外的基礎建設,更具成本效益的同時也不會影響市容。」

肯辛頓與切爾西區目前計畫安裝的是ubitricity 提供的「SimpleSockets」充電系統,最大輸出功率為4.6 kW。

OVO 表示,SimpleSockets 將會設立在付費和非付費停車格附近的路燈內,24 小時提供使用,每度電只需15 便士(約台幣6 元),這讓電動車不僅更為方便,花費也將更貼近一般人生活。

雖然SimpleSockets 每度電收取的費用與該區的電費規定相當,但Electrek 報導也指出,用戶必須每月繳納7.99 英鎊(約台幣320 元)的訂閱費,同時向ubitricity 購買199 英鎊(約台幣7,960 元)的電纜,才能使用這項收費標準。

當然用戶也可以選擇不繳納訂閱費,但使用上還是必須花100 多英鎊(約台幣4,000 元)購買使用的電纜,同時每度電的收費也將提高到19 便士(約台幣7.6 元),只是即使如此,也遠比英國國內的其他充電選擇好上許多。

ubitricity 目前已經開始在肯辛頓與切爾西區內進行安裝,目標在1 月底前要安裝完成50 個在路燈座內的充電裝置。

(合作媒體:。首圖來源: 臉書)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

網頁設計最專業,超強功能平台可客製化

聚甘新

詳說tcp粘包和半包

tcp服務端和客戶端建立連接後會長時間維持這個連接,用於互相傳遞數據,tcp是以流的方式傳輸數據的,就像一個水管里的水一樣,從一頭不斷的流向另一頭。
理想情況下,發送的數據包都是獨立的,

現實要複雜一些,發送方和接收方都有各自的緩衝區。
發送緩衝區:應用不斷的把數據發送到緩衝區,系統不斷的從緩衝區取數據發送到接收端。
接收緩衝區:系統把接收到的數據放入緩衝區,應用不斷的從緩衝區獲取數據。
當發送方快速的發送多個數據包時,每個數據包都小於緩衝區,tcp會將多次寫入的數據放入緩衝區,一次發送出去,服務器在接收到數據流無法區分哪部分數據包獨立的,這樣產生了粘包。

或者接收方因為各種原因沒有從緩衝區里讀取數據,緩衝區的數據會積壓,等再取出數據時,也是無法區分哪部分數據包獨立的,一樣會產生粘包。
發送方的數據包大於緩存區了,其中有一部分數據會在下一次發送,接收端一次接收到時的數據不是完整的數據,就會出現半包的情況。

我們可以還原一下粘包和半包,寫一個測試代碼
服務端

func main() {
	l, err := net.Listen("tcp", ":8899")
	if err != nil {
		panic(err)
	}
	fmt.Println("listen to 8899")
	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		} else {
			go handleConn(conn)
		}
	}
}

func handleConn(conn net.Conn) {
	defer conn.Close()
	var buf [1024]byte
	for {
		n, err := conn.Read(buf[:])
		if err != nil {
			break
		} else {
			fmt.Printf("recv: %s \n", string(buf[0:n]))
		}
	}
}

客戶端

func main() {
	data := []byte("~測試數據:一二三四五~")
	conn, err := net.Dial("tcp", ":8899")
	if err != nil {
		panic(err)
	}
	for i := 0; i < 2000; i++ {
		if _, err = conn.Write(data); err != nil {
			fmt.Printf("write failed , err : %v\n", err)
			break
		}
	}
}

查看一下輸出

recv: ~測試數據:一二三四五~
recv: ~測試數據:一二三四五~ ~測試數據:一二三四五~ 
recv: ~測試數據:一� 
recv: ��三四五~ ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~
recv: ~測試數據:一二三四五~ ~測試數據:一二三四五~ ~測試數據:一二三四五~ ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~

正常情況下輸出是recv: ~測試數據:一二三四五~,發生粘包的時候會輸出多個數據包,當有半包的情況下輸出的是亂碼數據,再下一次會把剩下的半包數據也輸出。
要解決也簡單的就想辦法確定數據的邊界,常見的處理方式:

  • 固定長度: 比如規定所有的數據包長度為100byte,如果不夠則補充至100長度。優點就是實現很簡單,缺點就是空間有極大的浪費,如果傳遞的消息中大部分都比較短,這樣就會有很多空間是浪費的,同樣浪費的還有流量。
  • 分隔符:用分隔符來確定數據的邊界,這樣做比較簡單也不浪費空間,但數據包內就不能包含相應的分隔符,如果有會造成錯誤的解析。
  • 數據頭:通過數據頭部來解析數據包長度,比如用4個字節來當數據頭,保存每個實數據包的長度。

個人更推薦數據頭方式來確定數據邊界,在發送和接收數據時做好規定,每個數據包是不定長的,比如4字節的包頭+真實的數據可以根據自己的業務進行擴展,比如上更多的包頭或者包尾,加上數據校驗等。
我修改一下上面的代碼:
客戶端

	data := []byte("~測試數據:一二三四五~")
	conn, err := net.Dial("tcp", ":8899")
	if err != nil {
		panic(err)
	}
	for i := 0; i < 2000; i++ {
		var buf [4]byte
		bufs := buf[:]
		binary.BigEndian.PutUint32(bufs, uint32(len(data)))
		if _, err := conn.Write(bufs); err != nil {
			fmt.Printf("write failed , err : %v\n", err)
			break
		}
		if _, err = conn.Write(data); err != nil {
			fmt.Printf("write failed , err : %v\n", err)
			break
		}
	}

服務端

func main() {
	l, err := net.Listen("tcp", ":8899")
	if err != nil {
		panic(err)
	}
	fmt.Println("listen to 8899")
	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		} else {
			go handleConn(conn)
		}
	}
}
func handleConn(conn net.Conn) {
	defer conn.Close()
	for {
		var msgSize int32
		err := binary.Read(conn, binary.BigEndian, &msgSize)
		if err != nil {
			break
		}
		buf := make([]byte, msgSize)
		_, err = io.ReadFull(conn, buf)
		if err != nil {
			break
		}
		fmt.Printf("recv: %s \n", string(buf))
	}
}

執行再看一下輸出,沒有粘包或者半包的情況

recv: ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~ 
recv: ~測試數據:一二三四五~

也可以像第一個例子一樣用一個指定大小的buf var buf [1024]byte,每次從conn里取出指定大小的數據,然後進行數據解析,如果發現有半包的情況,就再讀取一次,加上上次未解析的數據,再次重新解析。

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

【其他文章推薦】

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

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

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

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

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

網頁設計最專業,超強功能平台可客製化

聚甘新

為什麼Web開發人員在2020年不用最新的CSS功能

轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。

原文出處:https://dzone.com/articles/why-masses-are-not-using-latest-css-features-in-20

 

儘管CSS每年都會發布全新的特性,但實際上這些新功能很少會被web開發人員實際在生產項目中使用到,甚至去了解它們的動力也不會比去多完成幾個需求更多。那究竟是什麼原因導致的呢? 

1.使用最新特性不是優先事項

在一個新項目的初期階段,它用到的可能只是幾條CSS規則,但隨着項目的持續更新和迭代,項目中使用到的規則就會變得越來越複雜,CSS也會越來越複雜尺寸也會隨之不斷膨脹。因此,作為項目優化的第一要務,作為資源的CSS需要盡可能的精簡和減少複雜度,第一是為了便於更好地理解和維護,第二也是為了加載更為高效。那麼,更實用且可投入生產環境的一些CSS特性會被高頻使用,其他的特性則會被暫時擱置一旁。

並且,在一般情況下,樣式和品牌在一段時間內都會相對固定,完成任務的需求要比使用最新CSS的特性要更緊迫。 

 

 

(圖片來源於網絡)

 

2.預算限制

預算成本是影響了所有項目的主要因素。它在開發階段會高度影響事項的優先級。集成新的CSS功能需要時間,而開發團隊來說,增加的這部分時間成本會影響到項目的整體進度。因此,開發進度會重視在優化其他功能(而不是CSS功能)時花費的時間成本。

另外,引入了最新的CSS特性,還可能會使開發團隊把一部分精力放在解決瀏覽器兼容性問題上。這點和JavaScript不同,JavaScript有Babel來完成編譯,而CSS沒有提供類似功能。

 

 

 (圖片來源於網絡)

 

3.社區發展還未跟上

JavaScript每隔一段時間舉行一次會議。同樣,Vue和React也會為了幫助開發人員跟上社區的步伐而定期舉行會議。但是,對於CSS而言,它們根本沒有這樣的活動!因此,開發人員很難掌握其功能和路線圖。他們應該如何保持對新功能發展趨勢的了解? 沒有版本發布說明,也沒有定期的發布會,這根本不能點燃社區用戶的學習激情。 

對普通用戶而言,既然舊的技術已經滿足了需求,那麼又何必那麼麻煩閱讀文檔學習新的功能呢?

和框架和其他編程語言不同,CSS沒有針對安全問題的補丁程序。他只是一套標準,反正大多數客戶只需要關心網站看起來UI差不多就行了。

4.很難提升簡歷的含金量

即使你在掌握CSS方面付出了很多的努力,對CSS的新特性也了如指掌,但你也很難向你的客戶或老闆證明這一點,因為類似像這樣“熟練掌握CSS3以外的CSS特性”對他人而講是沒有意義的,因為它不是CSS3。在CSS開發領域,CSS3的出現是很有意義的,因為它完成了前端領域的統一:

  • Web開發人員提升了技能
  • 加速瀏覽器廠商統一支持了全新的CSS標準
  • 企業的技術棧更新

巨大的需求帶來了巨大的機會。除了大量的書籍、課程和視頻來幫助人們了解CSS3外,還催生了全新的布局模型,如Flexbox和Grid,儘管它們不是CSS3的一部分。

但這裏我們指的是CSS3外的特性,它們本身除了認可程度很低外,對開發團隊來講也是個相對不熟悉的東西,因此,開發團隊很難會把時間花在對市場沒有意義的事情上,客戶也不會關心你到底用不用新的技術。

5.缺乏時間

編寫CSS的主要目的是使你的網站的表現內容的形式更美觀及易於理解。CSS通過控制兩類事物來幫助開發人員去實現這個目標:布局和設計。布局(Layout)負責元素列和行排布,而設計(design)指顏色、字體、間距、動畫和邊框等基礎外觀。

但目前,舊的特性已經能處理的很好了,為什麼要花更多時間去使用新特性去替代已經很好的形式呢?

總結

CSS發布周期沒有固定的周期和計劃,導致一切都來的很突然 ,另外舊的CSS特性已經能很好的完成日常工作了,這讓很多Web開發人員沒有特別的動力去升級它們。

另外,新的特性知名度也不高,對最終用戶的吸引力也不足,很難從需求層面驅動使用。所以這就是為什麼都2020年了,CSS的新特性仍然使用的人較少的原因。

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

【其他文章推薦】

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

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

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

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

Python進階——詳解元類,metaclass的原理和用法

本文始發於個人公眾號:TechFlow,原創不易,求個關注

今天是Python專題第18篇文章,我們來繼續聊聊Python當中的元類。

在上上篇文章當中我們介紹了type元類的用法,在上一篇文章當中我們介紹了__new__函數與__init__函數的區別,以及它在一些設計模式當中的運用。這篇文章我們來看看metacalss與元類,以及__new__函數在元類當中的使用。

上一篇文章非常重要,是這一篇的基礎,如果錯過了上篇文章,推薦回顧一下:

Python面試常見問題,__init__是構造函數嗎?

metaclass

metaclass的英文直譯過來就是元類,這既是一個概念也可以認為是Python當中的一個關鍵字,不管怎麼理解,對它的內核含義並沒有什麼影響。我們可以不必糾結,就認為它是類的類的意思即可。在這個用法當中,支持我們自己定義一個類,使得它是後面某一個類的元類。

之前使用type動態創建類的時候,我們傳入了類名,和父類的tuple以及屬性的dict。在metaclass用法當中,其實核心相差不大,只是表現形式有所區別。我們來看一個例子即可:

class AddInfo(type):
    def __new__(cls, name, bases, attr):
        attr['info'] = 'add by metaclass'
        return super().__new__(cls, name, bases, attr)
        
        
class Test(metaclass=AddInfo):
    pass

在這個例子當中,我們首先創建了一個類叫做AddInfo,這是我們定義的一個元類。由於我們希望通過它來實現元類的功能,所以我們需要它繼承type類。我們在之前的文章當中說過,在Python面向對象當中,所有的類的根本來源就是type。也就是說Python當中的每一個類都是type的實例。

我們在這個類當中重載了__new__方法,我們在__new__方法當中傳入了四個參數。眼尖一點的小夥伴一定已經看出來了,這個函數的四個參數,正是我們調用type創建類的時候傳入的參數。其實我們調用type的方法來創建類的時候,就是調用的__new__這個函數完成的,這兩種寫法對應的邏輯是完全一樣的。

我們之後又創建了一個新的類叫做Test,這個當中沒有任何邏輯,直接pass。但是我們在創建類的時候指定了一個參數metaclass=AddInfo,這裏這個參數其實就是指定的這個類的元類,也就是指定這個類的創建邏輯。雖然我們用代碼寫了類的定義,但是在實際執行的時候,這個類是以metaclass為元類創建的。

根據上面的邏輯,我們可以知道,Test類在創建的時候就被賦予了類屬性info。我們可以驗證一下:

拓展類功能

上面這段就是元類的基本用法了,其實本質上和我們之前介紹的type的動態類創建是一樣的,只不過展現的形式不同。那麼我們就有一個問題要問了,我們使用元類究竟能夠做什麼呢?

這裡有一個經典的例子,我們都知道Python原生的list是沒有’add’這個方法的。假設我們習慣了Java當中list的使用,習慣用add來為它添加元素。我們希望創建一個新的類,在這個新的類當中,我們可以通過add來添加函數。通過元類可以很方便地使用這一點。

class ListMeta(type):
    def __new__(cls, name, bases, attrs):
        # 在類屬性當中添加了add函數
        # 通過匿名函數映射到append函數上
        attrs['add'] = lambda self, value: self.append(value)
        return super().__new__(cls, name, bases, attrs)
    
    
class MyList(list, metaclass=ListMeta):
    pass

我們首先是定義了一個叫做ListMeta的元類,在這個元類當中我們給類添加了一個屬性叫做add。它只是包裝了一下而已,底層是通過append方法實現的。我們來實驗一下:

從結果來看也沒什麼問題,我們成功通過調用add方法往list當中插入了元素。這裏藏着一個小細節,我們在ListMeta當中為attrs添加了一個名叫’add’的屬性。這個屬性是添加給類的,而不是類初始化出來的實例的。所以如果我們print出MyList這個類當中的所有屬性,也能看到add的存在。

如果我們直接去通過MyList去訪問add方法的話會引起報錯,因為我們實現add這個方法邏輯的匿名函數限制了需要傳入兩個參數。第一個參數是實例的對象self,第二個參數才是添加的元素value。如果我們通過MyList的類屬性去訪問它的話會觸發一個錯誤,因為缺少了一個參數。因為類當中的屬性實例也是可以調用的,並且Python會在參數前面自動添加self這個參數,就剛好滿足了要求。

搞明白了這些我們只是解決了可能性問題,我們明白了元類可以實現這樣的操作,但沒有解決我們為什麼必須要使用元類呢?就拿剛才的例子來說,我們完全可以繼承list這個類,然後在其中再開發我們想要的方法,為什麼一定要使用元類呢?

就剛才這個場景來說,的確,我們是找不出任何理由的。完全沒有理由不使用繼承,而非要用元類。但是在有些場景和有些問題當中,我們必須要使用元類不可。就是涉及類屬性變更和類創建的時候,我們來看下面這個例子。

控制實例的創建

還記得我們上篇文章介紹的工廠設計模式的例子嗎?就是我們可以通過參數來得到不同類的實例。

我們創建了三種遊戲的類和一個工廠類,我們重載了工廠類的__new__函數。使得我們可以根據實例化時傳入的參數返回不同類型的實例。

class Last_of_us:
    def play(self):
        print('the Last Of Us is really funny')
        
        
class Uncharted:
    def play(self):
        print('the Uncharted is really funny')
        

class PSGame:
    def play(self):
        print('PS has many games')
        
        
class GameFactory:
    games = {'last_of_us': Last_of_us, 'uncharted': Uncharted}
    def __new__(cls, name):
        if name in cls.games:
            return cls.games[name]()
        else:
            return PSGame()
        

uncharted = GameFactory('uncharted')
last_of_us = GameFactory('last_of_us')

假設這個需求完成得很好順利上線了,但是運行了一段時間之後我們發現下游有的時候為了偷懶會不通過工廠類來創建實例,而是直接對需要的類做實例化。原本這沒有問題,但是現在產品想要在工廠類當中加上一些埋點,統計出訪問我們工廠的訪問量。所以我們需要限制這些遊戲類不能直接實例化,必須要通過工廠返回實例

那麼這個功能我們怎麼實現呢?

我們分析一下問題就會發現,這一次不是需要我們在創建實例的時候做動態的添加,而是直接限制一些類不允許直接調用進行創建。限制的方法比較常用的一種就是拋出異常,所以我們希望可以給這些類加上一個邏輯,實例化類的時候傳入一個參數,表明是否是通過工廠類進行的,如果不是,則拋出異常

這裏,我們需要用到另外一個默認函數,叫做__call__,它是允許將類實例當做函數調用。我們通過類名來實例化,其實也是一個調用邏輯。這個__call__的邏輯並不難寫,我們隨手就來:

def __call__(self, *args, **kwargs):
    if len(args) == 0 or args[0] != 'factory':
        raise TypeError("Can't instantiate directly")

但問題是這個__call__函數並不能直接加在類當中,因為它的應用範圍是實例,而不是類。而我們希望的是在創建實例的時候進行限制,而不是對調用實例的時候進行限制,所以這段邏輯只能通過元類實現

我們直接創建類的時候就會觸發異常,因為不是通過工廠創建的。我們這裏判斷是否是工廠創建的邏輯簡化掉了,只是通過一個簡單的字符串來進行的判斷,實際上會用一些更加複雜的邏輯,這不是本文的重點,我們了解即可。

整體運行的邏輯和我們設想的一樣,說明這樣實現是正確的。

總結

我們日常開發當中用到元類的情況非常罕見,一般都是在一些高端開發的場景當中。比如說開發一些框架或者是中間件,為了方便下游的使用,需要創建一些關於類屬性的動態邏輯,才會用到元類。對於普通開發者而言,如果你無法理解元類的含義以及應用,也沒有關係,使用頻率非常低。

另外,元類的概念和動態類、動態語言的概念有關,Python語言的動態特性很多正是通過這一點體現的。所以隨着我們對於Python動態特性理解的加深,理解元類也會變得越來越容易,同樣也會理解越來越深刻。如果我們把Python的元類和裝飾器做一個類比的話,會發現兩者的核心邏輯是很類似的。本質上都是在原有的邏輯之外封裝新的邏輯,只不過裝飾器針對的是一段邏輯,而元類針對的是類的屬性和創建過程。

仔細思考,我相信一定會有靈光乍現的感覺。

今天的文章就到這裏,如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

本文使用 mdnice 排版

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

【其他文章推薦】

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

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

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

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

聚甘新

.NET Framework、.NET Core 和 .NET 5+ 的產品生命周期

.NET Framework、.NET Core 和 .NET 5+ 的產品生命周期

本文整理記錄了 .NET Framework、.NET Core 和 .NET 各個版本的產品支持周期和操作系統兼容性。

早於 .NET Framework 2.0 和 .NET Core 2.1 的 .NET 版本以及 .NET Core 2.2、.NET Core 3.0 已經停止了任何形式的支持,因此本文不做討論。

相關文章:

  • .NET Framework、.NET Core 和 .NET 5+ 的產品生命周期(本文)
  • Visual Studio 的產品生命周期
  • DevExpress 各個版本與 .NET、Visual Studio 的版本兼容性

.NET 版本說明

  • .NET Framework 4.5 是可替換計算機上的 .NET Framework 4 的就地更新,同樣,.NET Framework 4.5.1、4.5.2、4.6、4.6.1、4.6.2、4.7、4.7.1、4.7.2 和 4.8 是對 .NET Framework 4.5 的就地更新。 就地更新意味着它們使用相同的運行時版本,但是程序集版本會更新,並且包括新類型和成員。 安裝其中一個更新后,.NET Framework 4、.NET Framework 4.5、.NET Framework 4.6 或 .NET Framework 4.7 應用應繼續運行,而無需重新編譯。 但是,反過來則不行。 建議不要在較早版本的 .NET Framework 上運行面向更高版本的 .NET Framework 的應用。 例如,建議在 .NET Framework 4.5 上運行面向 .NET Framework 4.6 的應用。(參見 版本 4.5 及更高版本的備註)

  • .NET Core 為一個全新的跨平台框架,支持 Windows、Linux 和 macOS 等多種平台,以 MIT 協議完全開源。.NET Core 最早於 2014 年公布,首個版本 .NET Core 1.0 發佈於 2016 年。隨着版本的演進,.NET Core 不斷加入 .NET Framework 原有的功能,直到 .NET Core 3.1,完成這一進程。剩餘少量 .NET Core 不支持的 .NET Framework 技術 不再向 .NET Core 移植。

  • .NET Core 3.1 之後,隨着技術移植進程的結束,.NET Core 的後續版本將作為 .NET Framework 和 .NET Core 的繼任者,移除 “Core” 字樣直接稱作 “.NET”,版本號自 “.NET 5” 開始。因此,.NET Framework 4.8 將會是 .NET Framework 的最後一個版本。

.NET 支持政策

.NET Core 和 .NET 的版本類型

本節整理自 .NET Core 支持政策。

.NET Core/.NET 分為長期支持 (LTS) 版本和最新 (Current) 版本。自 .NET Core 2.2 起,兩者的支持周期如下:

  • LTS (Long Term Support): 在初始發布后的三年內受支持。
  • Current:在初始發布后,直到下一個 Current 或 LTS 版本發布后的三個月內受支持。

.NET Core 和 .NET 發布節奏

本節整理自 .NET 5 簡介

  • 自 2020 年起,每年 11 月為 .NET 發布新的主要版本,版本號自 5.0 起遞增。即 2020 年 11 月發布 .NET 5.0,2021 年 11 月發布 .NET 6.0,以此類推。

  • 自 2021 年起,將隔年發布的主要版本標記為 LTS 版本(即偶數的主要版本為 LTS 版本,奇數的為 Current 版本)。

.NET Core 和 .NET 生命周期詳情

本節整理自 .NET 5 簡介 以及 .NET Core 支持政策,僅列出了生命周期尚未結束的版本。

版本 初始發布時間 支持級別 結束支持時間
.NET 8 2023 年 11 月(預計) LTS 2025 年 11 月(預計)
.NET 7 2022 年 11 月(預計) Current 2023 年 2 月(預計)
.NET 6 2021 年 11 月(預計) LTS 2024 年 11 月(預計)
.NET 5 2020 年 11 月(預計) Current 2022 年 2 月(預計)
.NET Core 3.1 2019 年 12 月 3 日 LTS 2022 年 12 月 3 日
.NET Core 2.1 2018 年 5 月 30 日 LTS 2021 年 8 月 21 日

.NET Framework 各版本支持政策

本節內容整理自 .NET Framework 生命周期常見問題。

  • .NET Framework 4.5.2 及以上版本被定義為 Windows 操作系統的一個組件,與其父產品獲得相同的生命周期,詳見下節內容。

  • .NET Framework 4、4.5 和 4.5.1 已於 2016 年 1 月 12 日停止支持,客戶和開發人員必須就地更新到 .NET Framework 4.5.2 及以上版本,才能技術獲得技術支持和安全更新。

  • .NET Framework 3.5 SP1 在 Windows 10 v1809 和 Windows Server 2019 及以上版本中作為獨立的產品存在,自 2018 年 10 月 2 日起獲得 5 年主流支持和 5 年擴展支持。

  • .NET Framework 3.5 SP1 在 Windows 10 v1809 和 Windows Server 2019 以前的操作系統中,作為操作系統的組件存在,其生命周期與其父產品相同。

  • .NET Framework 2.0、3.0 和 3.5 已先後停止支持,客戶和開發人員可就地更新到 .NET Framework 3.5 SP1,以便在後者的生命周期內獲得技術支持和安全更新。由於 .NET Framework 3.5 依賴於 2.0 以及 3.0,因此 .NET Framework 2.0 SP2 和 .NET Framework 3.0 SP2 組件在安裝了 .NET Framework 3.5 SP1 環境當中得到支持。

.NET Framework 版本和操作系統版本的關係

本節內容整理自 .NET Framework 版本和依賴關係 以及 .NET Framework 系統需求。

  • .NET Framework 4.5 預裝在了 Windows 8 和 Windows Server 2012 中。此後,每個版本的 Windows 操作系統都包含了特定版本的 .NET Framework 4.x。

  • .NET Framework 4.8 預裝在了 Windows 10 v1903 (build 18362) 及以上版本中。

  • .NET Framework 4.6.1 及以上版本可以安裝在 Windows 7 和 Windows Server 2008 R2 SP1 及以上版本的 Windows 操作系統中,但不可以安裝低於預裝於操作系統中的版本。

  • .NET Framework 4.6 為 Windows Vista 和 Windows 2008 SP2 支持的最高版本。

  • .NET Framework 4.0.3 為 Windows XP 和 Windows Server 2003 支持的最高版本。(參見 在 Windows XP 和 Windows Server 2003 上安裝 .NET Framework)

    注意:.NET Framework 4、.NET Framework 4.0.3 和 Windows XP、Windows Server 2003 已經停止支持,不會再接收任何形式的安全更新。

  • .NET Framework 3.5 SP1 在 Windows XP 和 Windows Server 2013 及以上版本的 Windows 操作系統中,可以使用 安裝程序 進行安裝。

  • .NET Framework 3.5 SP1 在 Windows 10,Window Server 2016 和 Windows Server 2019 中可以通過控制面板直接啟用。

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

【其他文章推薦】

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

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

※超省錢租車方案

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

網頁設計最專業,超強功能平台可客製化

聚甘新