露西催生禁令 英擬禁寵物店售未滿6個月貓犬

摘錄自2018年8月23日中央社報導

英格蘭地區擬禁止寵物店銷售6個月以下的幼貓幼犬,民眾僅可領養或從合法繁殖者購買,而催生禁令的是一隻名叫「露西」、出生繁殖場的可憐小狗。

英國廣播公司(BBC)報導,英格蘭地區將從10月1日禁止銷售不滿8週大的幼貓幼犬,並計劃進一步擴大,限制出售6個月大的幼貓幼犬。

英國環境、食物及鄉村事務部表示,民眾目前可以直接從合法繁殖者,或是從合法的第三方賣家購買幼貓幼犬。然而,由於第三方賣家售出的寵物沒有數量紀錄,難以控管。

動保團體表示,僅能推估每年大不列顛地區(Great Britain)售出數量約在4萬至8萬隻,而根據政府紀錄,英格蘭地區僅有不到100家第三方賣家(包含寵物店)有販售貓犬的合法執照。

英國環境食品及農村事務部大臣戈夫(Michael Gove)表示:「我們會消滅繁殖場,確保第三方不能再販售小貓、小狗。」

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

【其他文章推薦】

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

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

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

※超省錢租車方案

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

前所未見! 北極最厚冰區開始融化

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

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行銷專家,教你從零開始的技巧

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行銷專家,教你從零開始的技巧

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行銷專家,教你從零開始的技巧

聚甘新

一文梳理JavaScript 事件循環(Event Loop)

事件循環(Event Loop),是每個JS開發者都會接觸到的概念,但是剛接觸時可能會存在各種疑惑。

眾所周知,JS是單線程的,即同一時間只能運行一個任務。一般情況下這不會引發問題,但是如果我們有一個耗時較多的任務,我們必須等該任務執行完畢才能進入下一個任務,然而等待的這段時間常常讓我們無法忍受,因為我們這段時間什麼都不能做,包括頁面也是鎖死狀態。

好在,時代在進步,瀏覽器向我們提供了JS引擎不具備的特性:Web API。Web API包括DOM API、定時器、HTTP請求等特性,可以幫助我們實現異步、非阻塞的行為。我們可以通過異步執行任務的方法來解決單線程的弊端,事件循環為此而生

提問QAQ:為什麼JavaScript是單線程的?

多個線程表示您可以同時獨立執行程序的多個部分。確定一種語言是單線程還是多線程的最簡單方法是看它擁有有多少個調用堆棧。JS 只有一個,所以它是單線程語言。

將JS設計為單線程是由其用途運行環境等因素決定的,作為瀏覽器腳本語言,JS的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很複雜的同步問題。同時,單線程執行效率高。

1. Event Loop舊印象

大家熟悉的關於事件循環的機制說法大概是:主進程執行完了之後,每次從任務隊列里取一個任務執行。如圖所示,所有的任務分為同步任務和異步任務,同步任務直接進入任務隊列–>主程序執行;異步任務則會掛起,等待其有返回值時進入任務隊列從而被主程序執行。異步任務會通過任務隊列的機制(先進先出的機制)來進行協調。具體如圖所示:

同步和異步任務分別進入不同的執行環境,同步的進入主線程,即主執行棧,異步的進入任務隊列。主線程內的任務執行完畢為空,會去任務隊列讀取對應的任務,推入主線程執行。 上述過程的不斷重複就是我們所熟悉的Event Loop (事件循環)。但是promise出現之後,這個說法就不太準確了

2. Event Loop 後印象

2.1 理論

這裏首先用一張圖展示JavaScript的事件循環:

直接看這張圖,可能黑人問號已經出現在同學的腦海。。。

這裏將task分為兩大類,分別是macroTask(宏任務)和microTask(微任務).一次事件循環:先運行macroTask隊列中的一個,然後運行microTask隊列中的所有任務。接着開始下一次循環(只是針對macroTask和microTask,一次完整的事件循環會比這個複雜的多)。

那什麼是macroTask?什麼是microTask呢?

JavaScript引擎把我們的所有任務分門別類,一部分歸為macroTask,另外一部分歸為microTack,下面是類別劃分:

macroTask:

  • setTimeout
  • setInterval
  • setImmediate
  • requestAnimationFrame
  • I/O
  • UI rendering

microTask:

  • process.nextTick
  • Promise
  • Object.observe
  • MutationObserver

我們所熟悉的定時器就屬於macroTask,僅僅了解macroTask的機制還是不夠的。為直觀感受兩種隊列的區別,下面上代碼進行實踐感知。

2.2 實踐

以setTimeout、process.nextTick、promise為例直觀感受下兩種任務隊列的運行方式。

console.log('main1');

process.nextTick(function() {
    console.log('process.nextTick1');
});

setTimeout(function() {
    console.log('setTimeout');
    process.nextTick(function() {
        console.log('process.nextTick2');
    });
}, 0);

new Promise(function(resolve, reject) {
    console.log('promise');
    resolve();
}).then(function() {
    console.log('promise then');
});

console.log('main2');

別著急看答案,先以上面的理論自己想想,運行結果會是啥?

最終結果是這樣的:

main1
promise
main2
process.nextTick1
promise then

// 第二次事件循環
setTimeout
process.nextTick2

process.nextTick 和 promise then在 setTimeout 前面輸出,已經證明了macroTask和microTask的執行順序。但是有一點必須要指出的是。上面的圖容易給人一個錯覺,就是主進程的代碼執行之後,會先調用macroTask,再調用microTask,這樣在第一個循環里一定是macroTask在前,microTask在後。

但是最終的實踐證明:在第一個循環里,process.nextTick1和promise then這兩個microTask是在setTimeout這個macroTask里之前輸出的,這是因為Promises/A+規範規定主進程的代碼也屬於macroTask。

主進程這個macroTask(也就是main1、promise和main2)執行完了,自然會去執行process.nextTick1和promise then這兩個microTask。這是第一個循環。之後的setTimeout和process.nextTick2屬於第二個循環

別看上面那段代碼好像特別繞,把原理弄清楚了,都一樣 ~

requestAnimationFrame、Object.observe(已廢棄) 和 MutationObserver這三個任務的運行機制大家可以從上面看到,不同的只是具體用法不同。重點說下UI rendering。在HTML規範:event-loop-processing-model里敘述了一次事件循環的處理過程,在處理了macroTask和microTask之後,會進行一次Update the rendering,其中細節比較多,總的來說會進行一次UI的重新渲染。

3. 小結

總而言之,記住一次事件循環:先運行macroTask隊列中的一個,然後運行microTask隊列中的所有任務。接着開始下一次循環。

參考文獻:

  • 總是一知半解的Event Loop
  • 深入理解事件循環機制
  • JavaScript運行機制

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

聚甘新

新能源車夯,比亞迪前三季獲利有望跳增九成

中國電動汽車商比亞迪(BYD)周日公布,2016年前九個月盈餘最高有望年增逾九成(91%),主要受惠於中國政策大力推動節能汽車。

比亞迪有股神巴菲特光環加持,上個月又獲得三星入股,可謂左右逢源。據比亞迪表示,上半年獲利來到23億人民幣,較去年同期跳增384%,若連同本季獲利,今年前三季預估將成長83-91%。

比亞迪以製造電池起家,2003年併購秦川汽車後跨足汽車市場,並為日後進軍電動車鋪路。憑藉著電池技術領先同業,比亞迪在中國新能源車領域已先立於不敗之地,近年隨著環保法規轉嚴,比亞迪生產之油電混合車與全電動車業績更是蒸蒸日上。

三星七月下旬以約30億人民幣參與比亞迪新一輪募資,亦是著眼於中國新能源車的商機。不過在三星正式入股後,巴菲特掌舵的柏克夏海瑟威公司(Berkshire Hathaway)對比亞迪的持股比例,則從原先的9.1%稀釋至8.25%。

(本文內容由授權提供)

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

【其他文章推薦】

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

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

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

※超省錢租車方案

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

聚甘新

Tesla台灣旗艦店開幕,Model S 2017年在台上市

不論是在汽車、能源還是科技界,不論發生什麼事情都在大眾目光焦點的特斯拉 (Tesla),既三月份成立臺灣分公司之後有更進一步的動作。特斯拉的臺北旗艦店在今日 (9 月1 日) 在臺北信義商圈開幕,有興趣的人可以到店體驗特斯拉房車Model S,並且預約試駕和進一步訂購,預計明年 (2017) 第一季交車。

特斯拉看中臺灣在科技產業的樞鈕地位,因此在亞太區暨中國、香港、澳門、澳洲之後,選擇臺灣,成為特斯拉全球第25 個設立的國家。而在信義商圈新光三越A11 的台灣旗艦店,則是第204 家店。選在臺灣的首善之都臺北,則是著眼信義商圈是臺北最繁盛的購物商圈,對新事物的接受度高,因此選在新光三越A11 設旗艦店,並且還跟新光三越合作,在百貨公司的地下停車場設立充電站。

電動車要能方便,必須有足夠的的充電站。Tesla香港、澳門及台灣地區區域總監范菁怡表示,目前除了設在車主自家的居家充電站之外,還會與百貨商場、飯店合作,在停車場設置目的地充電站。未來特斯拉也將在高速公路沿線設置超級充電站,服務需長距離駕駛的特斯拉車子。

由於特斯拉代表新一代的潔淨能源運用型式,對於提高都市運輸效率和降低污染有顯著效果,因此除了特斯拉的代表和合作的百貨公司代表以外,臺北市政府也由副市長林欽榮出席。另外還有負責招商相關事務的行政院全球招商及攬才聯合服務中心何怡明執行長,以及經濟部工業局黃裕峰副組長出席。林欽榮致詞時表示,臺北市仍然要繼續推動共享汽車,U-Car 計畫。

儘管目前在臺灣還只能預購特斯拉的Model S 房車車型,但是特斯拉計畫在臺引進平價車款Model 3,定價3 萬5,000 美元,預計明年引進,目前正在商品檢驗階段。

「電動車勢必是未來交通方式的主流,Tesla 一直期望扮演推動永續能源應用的角色。我們樂見台灣對環保、綠色能源的高接受度,也很高興Tesla 能成為這波改革中的一股力量。」Tesla 全球副總裁暨亞太區總裁任宇翔表示:「臺灣特殊的地理和城市發展環境,以及政府對於相關政策和補助的支持,讓Tesla 清楚看到電動車在臺灣的發展性。臺灣廠商不僅是Tesla供應鏈的合作夥伴,更在電動車的推廣上佔有重要地位。隨著Tesla 電動車在台上市與充電站的逐步擴充,Tesla 對臺灣市場的發展潛力深具信心,除了希望對合作夥伴和經濟發展帶來正面影響,更期望與臺灣一起開創電動車的新篇章。」

特斯拉之後將在臺灣設立客服,還有佈建充電網路,當特斯拉的Model S 在臺灣的道路奔馳時,超級充電站和目的地充電站在商圈、景點等地方,形成足夠的網狀分佈,維持特斯拉的輪胎不停轉動。全球有超過9,000 萬臺汽車,目前只有不到0.2% 的汽車是電動車,特斯拉推動電動車,還可以有很大的施力空間。

(首圖:設在新光三越信義A11 地下4 樓停車場的特斯拉目的地充電站,在2017 年特斯拉車子在臺灣道路奔馳之際,這類設在購物商場的充電站將會越來越多。來源:科技新報)

(本文授權轉載自《》──〈〉)

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

聚甘新

循序漸進VUE+Element 前端應用開發(11)— 圖標的維護和使用,循序漸進VUE+Element 前端應用開發(5)— 表格列表頁面的查詢,列表展示和字段轉義處理,循序漸進VUE+Element 前端應用開發(9)— 界面語言國際化的處理

在VUE+Element 前端應用中,圖標是必不可少點綴界面的元素,因此整合一些常用的圖標是非常必要的,還好Element界面組件裏面提供了很多常見的圖標,不過數量不是很多,應該是300個左右吧,因此考慮擴展更多圖標,我引入了vue-awesome組件,它利用了Font Awesome的內置圖標,實現了更多圖標的整合,可以在項目中使用更多的圖標元素了,另外在本隨筆的圖標管理中,提供了對圖標名稱進行搜索,並根據圖標顏色樣式生成對應圖標的代碼,非常方便使用。

Vue-Awesome 是基於 Vue.js 的 SVG 圖標組件,內置圖標來自  Font Awesome。

本篇隨筆先來上一個圖標管理的界面效果,然後在逐一進行介紹Element內置圖標和Vue-Awesome的圖標吧。

Element圖標管理界面如下:

基於Vue-Awesome的圖標管理如下所示。

其中查詢提供了名稱進行圖標查詢,以及限制一次性展示多少個,另外提供一個自定義顏色選項,從而可以改變圖標的展示顏色。

  

1、Vue-Awesome的使用介紹

  Vue-Awesome 的 npm的安裝命令如下所示:

npm install vue-awesome

安裝方式如下所示

import Vue from 'vue'

/* 在下面兩種方式中任選一種 */

// 僅引入用到的圖標以減小打包體積
import 'vue-awesome/icons/flag'

// 或者在不關心打包體積時一次引入全部圖標
import 'vue-awesome/icons'

/* 任選一種註冊組件的方式 */

import Icon from 'vue-awesome/components/Icon'

// 全局註冊(在 `main .js` 文件中)
Vue.component('v-icon', Icon)

// 或局部註冊(在組件文件中)
export default {
  components: {
    'v-icon': Icon
  }
}

界面使用代碼如下所示,詳細Demo可以參考https://justineo.github.io/vue-awesome/demo/ 了解。

<!-- 基礎用法 -->
<v-icon name="beer"/>

<!-- 添加選項 -->
<v-icon name="sync" scale="2" spin/>
<v-icon name="comment" flip="horizontal"/>
<v-icon name="code-branch" label="Forked Repository"/>

<!-- 堆疊圖標 -->
<v-icon label="No Photos">
  <v-icon name="camera"/>
  <v-icon name="ban" scale="2" class="alert"/>
</v-icon>

Vue-Awesome圖標提供了一些prop的屬性設置,參考下面列表所示。

  • name: string

    圖標名稱。如果本組件沒有用作圖標堆棧的容器,那麼這個字段是必須的。所有合法的值都對應於圖標文件相對於 icons 目錄的路徑。請注意當你在 FontAwesome 官網查找到圖標名詞后,需要確認一下圖標集的名稱。比如,在 500px 這個圖標的詳情頁會有一個 URL 參數 style=brands,故圖標名稱就是 brands/500px

    默認情況下,只能使用 FontAwesome 的免費圖標,另外由於 solid 樣式中的圖標最多,我們將其設為了默認圖標集,所以路徑前綴可以省略。

    當傳入 null 時,整個組件將不會渲染。

  • scale: number|string

    用來調整圖標尺寸,默認值為 1

  • spin: boolean

    用來指定圖標是否需要旋轉。默認值為 false。(不能與 pulse 一同使用。)

  • pulse: boolean

    用來指定圖標是否有脈衝旋轉的效果。默認值為 false。(不能與 spin 一同使用。)

  • inverse: boolean

    為 true 時圖標顏色將被設置為 #fff。默認值為 false

  • flip: 'vertical'|'horizontal'|'both'

    用來指定圖標是否需要翻轉。

  • label: string

    當指定時會設置圖標的 aria-label

  • title: string

    為圖標設置標題。

另外,我們也可以註冊自定義圖標,如下所示。

import Icon from 'vue-awesome/components/Icon'

Icon.register({
  baidu: {
    width: 23.868,
    height: 26,
    d: 'M3.613 13.701c2.827-.608 2.442-3.986 2.357-4.725-.138-1.139-1.477-3.128-3.296-2.971C.386 6.21.052 9.515.052 9.515c-.309 1.528.74 4.793 3.561 4.186zm3.002 5.875c-.083.238-.268.846-.107 1.375.315 1.187 1.346 1.24 1.346 1.24h1.48v-3.619H7.749c-.713.213-1.057.767-1.134 1.004zM8.86 8.035c1.562 0 2.823-1.797 2.823-4.019C11.683 1.796 10.421 0 8.86 0 7.301 0 6.036 1.796 6.036 4.016c0 2.222 1.265 4.019 2.824 4.019zm6.724.265c2.087.271 3.429-1.956 3.695-3.644.272-1.686-1.074-3.644-2.552-3.98-1.48-.339-3.329 2.032-3.497 3.578-.2 1.89.271 3.778 2.354 4.046zm5.114 9.923s-3.229-2.498-5.113-5.198c-2.555-3.981-6.185-2.361-7.399-.337-1.209 2.024-3.093 3.305-3.36 3.644-.271.334-3.9 2.293-3.095 5.871.806 3.576 3.635 3.508 3.635 3.508s2.085.205 4.504-.336c2.42-.537 4.503.134 4.503.134s5.652 1.893 7.199-1.751c1.545-3.645-.874-5.535-.874-5.535zm-9.671 5.423H7.352c-1.587-.316-2.219-1.4-2.299-1.584-.078-.188-.528-1.059-.29-2.539.686-2.219 2.642-2.379 2.642-2.379h1.956V14.74l1.666.025v8.881zm6.844-.025h-4.229c-1.639-.423-1.716-1.587-1.716-1.587v-4.677l1.716-.027v4.203c.104.447.661.529.661.529h1.742v-4.705h1.825v6.264zm5.986-12.486c0-.808-.671-3.239-3.159-3.239-2.492 0-2.825 2.295-2.825 3.917 0 1.548.131 3.71 3.227 3.641 3.096-.068 2.757-3.507 2.757-4.319z'
  }
})

如果你的 SVG 文件有多個路徑或多邊形,以及/或者你想預定義一些樣式,可以用如下方式進行註冊:

路徑方式:

import Icon from 'vue-awesome/components/Icon'

Icon.register({
  webpack: {
    width: 1200,
    height: 1200,
    paths: [
      {
        style: 'fill:#8ED6FB',
        d: 'M1035.6 879.3l-418.1 236.5V931.6L878 788.3l157.6 91zm28.6-25.9V358.8l-153 88.3V765l153 88.4zm-901.5 25.9l418.1 236.5V931.6L320.3 788.3l-157.6 91zm-28.6-25.9V358.8l153 88.3V765l-153 88.4zM152 326.8L580.8 84.2v178.1L306.1 413.4l-2.1 1.2-152-87.8zm894.3 0L617.5 84.2v178.1l274.7 151.1 2.1 1.2 152-87.8z'
      },
      {
        style: 'fill:#1C78C0',
        d: 'M580.8 889.7l-257-141.3v-280l257 148.4v272.9zm36.7 0l257-141.3v-280l-257 148.4v272.9zm-18.3-283.6zM341.2 436l258-141.9 258 141.9-258 149-258-149z'
      }
    ]
  }
})

多邊形方式:

import Icon from 'vue-awesome/components/Icon'
Icon.register({
  vue: {
    width: 256,
    height: 221,
    polygons: [
      {
        style: 'fill:#41B883',
        points: '0,0 128,220.8 256,0 204.8,0 128,132.48 50.56,0 0,0'
      },
      {
        style: 'fill:#35495E',
        points: '50.56,0 128,133.12 204.8,0 157.44,0 128,51.2 97.92,0 50.56,0'
      }
    ]
  }
})

對於自定義的這些圖標,我們可以把它們一起放在一個獨立的JS文件裏面進行定義,然後全局統一加入即可。

 

 使用上和其他的圖標沒有差異,只是名稱不同而已。

    <div style="height:100px;padding:10px">
      <span>vue-Awesome 自定義圖標:(在utils/awesome-icon-customed.js中引入)</span>
      <v-icon name="baidu" scale="2" :style="iconStyle" />
      <v-icon name="vue" scale="2" />
      <v-icon name="webpack" scale="2" spin />
      <v-icon name="html5-c" scale="2" spin />
    </div>

 

2、導入Element 圖標和Vue-Awesome圖標

在我們進行頁面管理的時候,我們需要提取Element 圖標和Vue-Awesome圖標,以便能夠進行界面的展示處理。

Element圖標,我們只需要在一個JS文件裏面,包含它的名稱進去一個列表裡面即可,如下定義所示。

const elementIcons = [
  'platform-eleme', 'eleme', 'delete-solid', 'delete', ..........
]

export default elementIcons

在其中錄入對應Element的圖表名稱,移除el-icon-的前綴即可構成所需列表的每項內容。

而對於Vue-Awesome圖標,我們安裝對應的組件后,它的圖標資源肯定也一定下載下來了,我們找到對應的node_modules 目錄下的文件就可以看到了,如下截圖所示。

 可以看到它的每個圖標對應一個js文件,而且不同樣式還有不同的目錄的,我們只需要自動加入對應的文件名稱即可。

定義一個js文件,如vue-awesome-icon.js,用來獲取對應Awesome圖標名稱,如下邏輯所示 

// Vue-Awesome圖標自動加入
const req = require.context('vue-awesome/icons', true, /\.js$/)
const requireAll = requireContext => requireContext.keys()

const re = /\.\/(.*)\.js/

const vueAwesomeIcons = requireAll(req).filter((key) => {
  return key.indexOf('index.js') < 0
}).map(i => {
  return i.match(re)[1]
})

export default vueAwesomeIcons

通過 require.context 的操作以及僅需filter的數組過濾,我們就可以獲得對應的Awesome圖標名稱了。

在管理頁面裏面,我們需要引入Element和Vue-Awesome的圖標管理文件,如下所示。

import elementIcons from './element-icons' // 引入Element圖標
import vueAwesomeIcons from './vue-awesome-icons' // 引入vue-awesome圖標

然後構造頁面的data數據,如下所示,其中searchForm 是用來承載查詢條件的。

export default {
  name: 'Icons',
  data() {
    return {
      // 查詢表單
      searchForm: {
        label: '',
        pagesize: 50,
        color: '#409EFF'
      },
      // 自定義svg圖標集合
      svgIcons,
      // element圖標集合
      elementIcons,
      // vueAwesome圖標集合
      vueAwesomeIcons
    }
  },

然後增加幾個Computed函數,用來處理數據的過濾查詢等操作。

 computed: {
    iconStyle: function() {
      return { color: this.searchForm.color }
    },
    elementIconsFiltered: function() {
      const that = this
      var list = that.elementIcons.filter(item => {
        return item.indexOf(that.searchForm.label) >= 0
      })
      if (that.searchForm.pagesize > 0) {
        return list.slice(0, that.searchForm.pagesize)
      } else {
        return list
      }
    },
    vueAwesomeIconsFiltered: function() {
      const that = this
      var list = that.vueAwesomeIcons.filter(item => {
        return item.indexOf(that.searchForm.label) >= 0
      })
      if (that.searchForm.pagesize > 0) {
        return list.slice(0, that.searchForm.pagesize)
      } else {
        return list
      }
    }
  },

然後在method裏面,對常規的圖標進行生成處理即可。

  methods: {
    generateElementIconCode(symbol) {
      return `<i class="el-icon-${symbol}" style="color:${this.searchForm.color};"/>`
    },
    generateAwesomeIconCode(symbol) {
      return `<v-icon name="${symbol}" style="color:${this.searchForm.color};"/>`
    },
    handleClipboard(text, event) {
      if (text) {
        clipboard(text, event)
      }
    }
  }

對於界面的展示,我們以Vue-awesome圖標展示為例介紹,如下所示。

      <el-tab-pane label="Vue-Awesome 圖標">
        <div
          v-for="item of vueAwesomeIconsFiltered"
          :key="item"
          @click="handleClipboard(generateAwesomeIconCode(item),$event)"
        >
          <el-tooltip placement="top">
            <div slot="content">{{ generateAwesomeIconCode(item) }}</div>
            <div class="icon-item">
              <v-icon :name="item" scale="2" :style="iconStyle" />
              <span>{{ item }}</span>
            </div>
          </el-tooltip>
        </div>
      </el-tab-pane>

這樣就可以實現對應圖標的動態過濾和展示了。

 

 

列出一下前面幾篇隨筆的連接,供參考:

循序漸進VUE+Element 前端應用開發(1)— 開發環境的準備工作

循序漸進VUE+Element 前端應用開發(2)— Vuex中的API、Store和View的使用

循序漸進VUE+Element 前端應用開發(3)— 動態菜單和路由的關聯處理

循序漸進VUE+Element 前端應用開發(4)— 獲取後端數據及產品信息頁面的處理

循序漸進VUE+Element 前端應用開發(5)— 表格列表頁面的查詢,列表展示和字段轉義處理

循序漸進VUE+Element 前端應用開發(6)— 常規Element 界面組件的使用

循序漸進VUE+Element 前端應用開發(7)— 介紹一些常規的JS處理函數

循序漸進VUE+Element 前端應用開發(8)— 樹列表組件的使用

循序漸進VUE+Element 前端應用開發(9)— 界面語言國際化的處理

 

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

【其他文章推薦】

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

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

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

※超省錢租車方案

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

聚甘新

Redis 數據結構 之 SDS

SDS(simple dynamic string),簡單動態字符串。s同時它被稱為 Hacking String。hack 的地方就在 sds 保存了字符串的長度以及剩餘空間。sds 的實現在 sds.c 中。

C語言字符串使用長度為n+1的字符數組來表示長度為n的字符串,並且字符數組的最後一個元素總是空字符’\0’,這樣的方式存儲,時存在安全隱患的,並且它不能滿足效率方面的需求。

因此Redis沒有使用C原生的string而是自己構建了SDS。在Redis里,C語言字符串只用於一些無須對字符串值進行修改的地方,比如:日誌。

在Redis中,包含字符串值的鍵值對都是使用SDS實現的,除此之外,SDS還被用於AOF緩衝區、客戶端狀態的輸入緩衝區。

SDS定義

struct sdshdr{
     //字節數組
     char buf[]; 
     //buf數組中已使用字節數量
     int len;
     //buf數組中未使用字節數量
     int free;
}

如上圖所示,len表示該SDS保存了一個6字節長度(不包含結束符)的字符串,free表示該SDS還有6個字節的未使用空間,buf是一個char類型的數組 ,保存了該SDS所存儲的字符串值。

高效

相比C語言字符串,使獲取字符串長度時間複雜度降為O(1)而C原生的獲取長度為O(N) 遍歷整個數組。

安全

同時SDS杜絕緩衝區溢出,不會像C那樣造成數組數據不安全,絕對不會越界。

當需要對SDS進行修改時,API會先檢查SDS當前剩餘空間是否滿足修改之後所需的空間,如果不滿足的話API會自動將SDS的空間擴展至足夠用的空間然後才進行下一步操作,所以SDS不會出現緩衝區溢出問題。

減少內存分配

C語言字原生符串底層是使用一個n+1個字符長度的char類型數據實現的,所以每次增長或縮短一個原生字符串,程序都要對這個字符串數組進行一次內存重分配操作:

同時因為內存重分配涉及複雜的算法,並且可能需要執行系統調用,所以它通常是一個比較耗時的操作。Redis經常被用於速度要求嚴苛、數據被頻繁修改的場合,如果每次修改字符串都需要執行一次內存重分配的話,那麼對於性能會造成很大影響。

SDS 在分配了內存之後(往往空間會存在盈餘,也就是空間的預分配),然後自己通過len 和 free 來維護已使用的和未使用的內存,不再依賴系統來重新劃分,這樣能有效的提升性能。

空間預分配

用於字符串增長操作,當字符串增長時,程序會先檢查需不需要對SDS空間進行擴展,如果需要擴展,程序不僅會為SDS分配修改所必要的空間,還會為SDS分配額外的未使用空間,額外分配的未使用空間公式如下:

SDS空間 < 1MB

如果對SDS修改之後,SDS的長度(修改之後len屬性的值)小於1MB,那麼則分配和len屬性同樣大小的未使用空間,這時SDS的len屬性和free屬性的值相同。如:如果修改之後SDS的len將變為10字節,那麼程序也會分配10字節的未使用空間,SDS的buf數組實際長度變為10 + 10 + 1 = 21(額外一個字節用於保存結束符\n)

SDS空間 > 1MB

如果對SDS修改之後,SDS的長度大於等於1MB,那麼程序會分配1MB的未使用空間。如:修改之後的len將變為10MB,那麼程序會分配1MB的未使用空間,SDS的bug數組長度為10MB + 1MB + 1byte

SDS空間 > 512MB

Game over~ 報錯!

惰性空間釋放

用於優化SDS的字符串收縮操作,當字符串收縮時,程序不會立即執行內存重分配來回收收縮后內存多出來的空間,而是使用free屬性記錄下來,以備將來使用。

通過空間預分配,Redis可以減少連續執行字符串增長操作所需的內存重分配次數,通過惰性空間釋放,SDS避免了縮短字符串時所需的內存重分配操作,併為將來由可能的增長操作提供了優化。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

聚甘新