標籤: 銷售文案

  • 高雄鼓勵換電動機車 最高補助額達 2.3 萬

    高雄市機車總數達 201 萬輛,成為都市的污染源之一,為了鼓勵機車族更換電動機車,高雄市政府環保局推動補助政策,換車最高可獲得 2.3 萬元的補助。   高雄市政府環境保護局空噪科長鄭嵐 26 日下午表示,根據交通部機動車輛統計資料,高雄市截至 103 年 12 月底掛牌的使用中機車,總數約 201 萬輛,為鼓勵民眾汰舊換購電動車輛,高雄市環保局持續推動淘汰補助方案,除了經濟部工業局補助純購電動機車,機車族可獲得補助 7,200 元到 10,000 元外,若搭配汰舊二行程機車,再加碼補助至 17,400 元到 23,000 元。   他表示,同時,為了提升友善充電環境,高雄環保局近年來也積極推動充電站架設,除了原有公用及私有充電站,103 年完成社區大樓與電動機車經銷商等 25 座,共有充電站 217 站,讓高雄市騎乘電動車市民處處皆有電可充,建構低碳生活圈。

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

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

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

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

  • 中國最大太陽能電動車充電站 於北京CBD首度投用

    據報導,位於中國北京CBD地區華茂中心停車場的太陽能電動汽車公共充電站於近日正式建成並投入試運營。這座中國目前最大的電動汽車智慧充電站共有100台充電樁,包括兩座地面太陽能智慧充電站和地下充電站。   該電站太陽能模組轉換效率達22%,裝機容量目前為25kW,投資額約為1300萬元人民幣(下同)。 此充電站收費標準初步定在1.37元人民幣/kWh,其中含有0.57元人民幣的基礎電費。其提供快充和慢充兩種充電服務,慢充最長時間為兩個半小時,快充僅需20分鐘。該充電站不僅可為市場上幾乎所有類型的電動車充電,且車主可通過手機達到預約、支付等充電操作。

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 發展電動車 梅克爾盼德國2030年前設百萬充電站

    摘錄自2019年11月3日中央通訊社德國報導

    德國總理梅克爾4日將與本國汽車工業代表會商,討論如何加速發展低碳排的電池驅動交通工具。她3日透過影片表示,德國在2030年前應設置100萬座電動車充電站。

    德國境內目前僅有約2萬座電動車公共充電站。梅克爾指出:「為達此(發展電動車)目的,我們想在2030年前設置100萬座充電站,而產業界將必須加入相關計畫。我們要談的就是這個。」

    路透社報導,預定明天在總理府舉行的會議,將是為相關議題舉辦的第二場,涉及儘速採取行動,以期交通運輸產業為德國達成國家碳排減量目標做出貢獻。會議將聚焦於汽油和柴油的替代方案,其中包括氫燃料和電池,以及政府和業界如何分攤給予消費者的補助,以刺激相關產品買氣。

    梅克爾表示,政府也將致力於保障就業機會。

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

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

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

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

  • 印度南部核電廠曾遭網攻 所幸系統未受影響

    摘錄自2019年10月31日中央社報導

    曾有印度媒體披露,印度核電公司(The NuclearPower Corporation of India, NCPIL)的古丹庫蘭(Kudankulam)核電廠系統曾於9月遭植入惡意軟體(malware)並受到網路攻擊。印度核電公司31日發表聲明證實,位於印度南部坦米爾那都省(TamilNadu)的古丹庫蘭核電廠曾遭網路攻擊,但聲明也強調,核電廠系統沒有受到影響。

    這份聲明也證實,公司的系統被植入惡意軟體,印度電腦緊急應變小組(CERT-In)9月4日發現這種狀況後已通知公司。

    聲明說,全案已由印度原子能部(Department ofAtomic Energy)專家進行調查,初步發現受感染的電腦屬於同一用戶,這名用戶的電腦曾與用於管理系統的網絡連結;受感染部份目前與關鍵內部網路隔離,且網路持續被監控中。核電廠系統沒有受到影響。

    原能會對此事件也發布新聞稿表示:我國運轉中核能電廠的發電及安全相關電腦數位設備都是獨立的系統,與外界實體隔離,阻絕網路攻擊的機會,並訂有隨身碟資訊設備及門禁管制程序,以避免駭客透過網際網路以外之其他方式入侵。

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 民主剛果抗伊波拉鬥士家中遇害 凶手動機不明

    摘錄自2019年11月4日中央社報導

    法新社報導,剛果民主共和國軍方4日表示說,一名協助傳遞對抗伊波拉(Ebola)疫情資訊的電台主持人,35歲的馬罕巴(Papy Mumbere Mahamba),他的妻子受傷,住家被縱火燒毀他的家。

    這起在動盪的伊圖里省(Ituri)魯汶巴鎮(Lwemba)發生的謀殺案,凶手犯案動機不明。

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

    【其他文章推薦】

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

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

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

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

    ※超省錢租車方案

  • 無人駕駛電動車?傳蘋果正在研發車類產品

    無人駕駛電動車?傳蘋果正在研發車類產品

      據知情人士透露,蘋果公司早在一年前就成立了汽車研發團隊,目前該團隊共有 100 多名員工,正在研發一款代號為 Titan 的電動車,同時蘋果公司與汽車產業中無人駕駛方面的資深人士互動頻繁,研發方向很有可能是一款無人駕駛的電動車。   蘋果公司對於汽車類產品和服務的研發計劃不僅僅局限在軟體系統,而是以打造整車為目標。在研發方面蘋果並沒有與傳統汽車廠商建立太多聯繫,據知情人士透露蘋果正在與汽車零組件廠商諮詢,主要是電力和車聯網方面的公司,這些諮詢並沒有涉及合作的部分。   蘋果公司已經招募了不少汽車產業的資深人士,包括前 Benz 北美研發中心的總裁 Johann Jungwirth,他在 2014 年 9 月加入蘋果四,此前曾負責 Benz 的自動駕駛、用戶界面設計、產品風格設計等工作。     本文全文授權轉載自《科技新報》─〈〉

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

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

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

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

  • 三星收購電池部門 傳將研發電動車

    蘋果(Apple)研發電動車的傳聞滿天飛,三星(Samsung)不甘示弱跟進,打算在電動車界跟蘋果再次一決雌雄?   韓聯社和 Tomˋs Hardware 報導,南韓電池製造龍頭 Samsung SDI 23 日宣布收購汽車零件商 Magna Steyr 的電池部門,購併金額未對外透露。   Tomˋs Hardware 網站認為,Samsung SDI 是 BMW i3 電動車的電池供應商,購併固然可能只是要強化電池部門實力,但也有可能代表三星打算跨足電動車。三星集團旗下業務橫跨電機、化學、造船、工具機等,如果真的要生產電動車,三星握有的技術資源更勝蘋果。

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 台達電電動車驅動馬達 打入福斯供應鏈

    電源供應器廠積極跨入車用市場,台達電耕耘 3 年的電動車驅動馬達打入福斯集團供應鏈,今年開始出貨;新巨微動開關則陸續取得德國雙 B、奧迪與福斯,美系福特和日系車廠訂單;康舒電源轉換器也與多家國際電動車大廠談合作。   台達電董事長海英俊表示,目前各國積極發展電動車,基礎設施也開始動起來,因此台達電最近在電動車零組件有不錯的進展,包括出貨給美國知名電動車廠充電樁、轉換器,台達電在歐、美、日、中國等各地的電動車標準都通過認證。   海英俊透露,台達電研發電動車驅動馬達,經過 3 年努力,已獲歐洲車廠認證。

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

    【其他文章推薦】

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

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

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

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

    ※超省錢租車方案

  • 使用 nuget server 的 API 來實現搜索安裝 nuget 包

    使用 nuget server 的 API 來實現搜索安裝 nuget 包

    使用 nuget server 的 API 來實現搜索安裝 nuget 包

    Intro

    nuget 現在幾乎是 dotnet 開發不可缺少的一部分了,還沒有用過 nuget 的就有點落後時代了,還不快用起來

    nuget 是 dotnet 里的包管理機制,類似於前端的 npm ,php 的 composer,java 里的 maven …

    nuget 定義了一套關於 nuget server 的規範,使得用戶可以自己實現一個 nuget server

    也正是這些規範,使得我們可以根據這些規範來實現 nuget server 的包管理的功能,今天主要介紹一下,根據 nuget server 的 api 規範使用原始的 HTTP 請求來實現 nuget 包的搜索和使用 nuget 提供的客戶端 SDK 來實現 nuget 包的搜索和下載

    Nuget Server Api

    Nuget 協議介紹

    nuget 的協議有好幾個版本,目前主要用的是 v3,開源的 nuget server Baget 也實現了基於 nuget protocal v3 的規範

    我們添加 nuget 源的時候會指定一個 source url,類似 https://api.nuget.org/v3/index.json 這樣的,着通常被稱為 Service Index,是一個 nuget 源的入口,有點類似於 Identity Server 里的發現文檔,通過這個地址可以獲取到一系列的資源的地址

    有一些資源是協議規範里定義的必須要實現的,有一些是可選的,具體參考官方文檔,以後隨着版本變化,可能會有差異,目前 nuget.org 提供的資源如下:

    Nuget.org 提供了兩種搜索的方式,

    一個是 SearchQuery,會根據包名稱、 tag、description 等信息去匹配關鍵詞,

    一個是 SearchAutocomplete 根據包名稱的前綴去匹配包的名稱

    獲取某個 nuget 包的版本信息,可以使用 PackageBaseAddress 來獲取

    ServiceIndex 返回的信息示例如下:

    返回的信息會有一個 resources 的數組,會包含各種不同類型的資源,對應的 @id 就是調用這種類型的API要用到的地址,下面來看一個搜索的示例

    在每個 API 的文檔頁面可以看到會使用的 @type,調用這個 API 的時候應該使用這些 @type 對應的資源

    這裏的 @id 就是上面的 resource 對應的 @id

    參數說明:

    q 搜索時所用的關鍵詞,

    skip/take 用來分頁显示查詢結果,

    prelease 用來指定是否限制預覽版的 package,true 包含預覽版的 nuget 包,false 只包含已經正式發布的 nuget 包

    semVerLevel 是用來指定包的語義版本

    The semVerLevel query parameter is used to opt-in to SemVer 2.0.0 packages. If this query parameter is excluded, only packages with SemVer 1.0.0 compatible versions will be returned (with the standard NuGet versioning caveats, such as version strings with 4 integer pieces). If semVerLevel=2.0.0 is provided, both SemVer 1.0.0 and SemVer 2.0.0 compatible packages will be returned. See the SemVer 2.0.0 support for nuget.org for more information

    packageType 用來指定 nuget 包的類型,目前支持的類型包括 Dependency(默認)項目依賴項,DotnetTool(dotnetcore 2.1 引入的 dotnet cli tool),Template (dotnet new 用) 自定義的項目模板

    其他的 API 可以自行參考官方文檔:https://docs.microsoft.com/en-us/nuget/api/service-index

    Packages

    SearchQuery 返回的信息比較多而且可能並不準確,適用於不清楚包的名稱的時候使用,如果知道 nuget 包的名稱(PackageId) ,可以使用 SearchAutocomplete 來搜索,這樣更精準,返回的信息也更簡單,只有匹配的 package 名稱

    通過原始 api 調用的方式實現 nuget 包的搜索

    using var httpClient = new HttpClient(new NoProxyHttpClientHandler());
    // loadServiceIndex
    var serviceIndexResponse = await httpClient.GetStringAsync(NugetServiceIndex);
    var serviceIndexObject = JObject.Parse(serviceIndexResponse);
    
    var keyword = "weihanli";
    
    //https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource
    var queryEndpoint = serviceIndexObject["resources"]
        .First(x => x["@type"].Value<string>() == "SearchQueryService")["@id"]
        .Value<string>();
    var queryUrl = $"{queryEndpoint}?q={keyword}&skip=0&take=5&prerelease=false&semVerLevel=2.0.0";
    var queryResponse = await httpClient.GetStringAsync(queryUrl);
    Console.WriteLine($"formatted queryResponse:");
    Console.WriteLine($"{JObject.Parse(queryResponse).ToString(Formatting.Indented)}");
    
    // https://docs.microsoft.com/en-us/nuget/api/search-autocomplete-service-resource
    var autoCompleteQueryEndpoint = serviceIndexObject["resources"]
        .First(x => x["@type"].Value<string>() == "SearchAutocompleteService")["@id"]
        .Value<string>();
    var autoCompleteQueryUrl = $"{autoCompleteQueryEndpoint}?q={keyword}&skip=0&take=5&prerelease=false&semVerLevel=2.0.0";
    var autoCompleteQueryResponse = await httpClient.GetStringAsync(autoCompleteQueryUrl);
    Console.WriteLine($"formatted autoCompleteQueryResponse:");
    Console.WriteLine($"{JObject.Parse(autoCompleteQueryResponse).ToString(Formatting.Indented)}");
    
    

    output 示例:

    Query 返回示例

    Autocomplete 返回結果

    從上面我們可以看到 Query 接口返回了很多的信息,Autocomplete 接口只返回了 package 的名稱,返回的信息更為簡潔,所以如果可以使用 Autocomplete 的方式就盡可能使用 Autocomplete 的方式

    Package Versions

    前面我們提到了可以使用 PackageBaseAddress 來查詢某個 nuget 包的版本信息,文檔地址:https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource,來看一下示例:

    using (var httpClient = new HttpClient(new NoProxyHttpClientHandler()))
    {
        // loadServiceIndex
        var serviceIndexResponse = await httpClient.GetStringAsync(NugetServiceIndex);
        var serviceIndexObject = JObject.Parse(serviceIndexResponse);
    
        // https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource
        var packageVersionsEndpoint = serviceIndexObject["resources"]
            .First(x => x["@type"].Value<string>() == "PackageBaseAddress/3.0.0")["@id"]
            .Value<string>();
    
        var packageVersionsQueryUrl = $"{packageVersionsEndpoint}/dbtool.core/index.json";
        var packageVersionsQueryResponse = await httpClient.GetStringAsync(packageVersionsQueryUrl);
        Console.WriteLine("DbTool.Core versions:");
        Console.WriteLine(JObject.Parse(packageVersionsQueryResponse)
                          .ToString(Formatting.Indented));
    }
    

    output 示例:

    注:api 地址中的 packageId 要轉小寫

    Nuget Client SDK

    除了上面的根據 api 自己調用,我們還可以使用 nuget 提供的客戶端 sdk 實現上述功能,這裏就不詳細介紹了,有需要可能查閱官方文檔:https://docs.microsoft.com/en-us/nuget/reference/nuget-client-sdk

    下面給出一個使用示例:

    var packageId = "WeihanLi.Common";
    var packageVersion = new NuGetVersion("1.0.38");
    
    var logger = NullLogger.Instance;
    var cache = new SourceCacheContext();
    // 在 SDK 的概念里,每一個 nuget 源是一個 repository
    var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
    
    // SearchQuery
    {
        var resource = await repository.GetResourceAsync<PackageSearchResource>();
        var searchFilter = new SearchFilter(includePrerelease: false);
    
        var results = await resource.SearchAsync(
            "weihanli",
            searchFilter,
            skip: 0,
            take: 20,
            logger,
            CancellationToken.None);
        foreach (var result in results)
        {
            Console.WriteLine($"Found package {result.Identity.Id} {result.Identity.Version}");
        }
    }
    // SearchAutoComplete
    {
        var autoCompleteResource = await repository.GetResourceAsync<AutoCompleteResource>();
        var packages =
            await autoCompleteResource.IdStartsWith("WeihanLi", false, logger, CancellationToken.None);
        foreach (var package in packages)
        {
            Console.WriteLine($"Found Package {package}");
        }
    }
    //
    {
        // get package versions
        var findPackageByIdResource = await repository.GetResourceAsync<FindPackageByIdResource>();
        var versions = await findPackageByIdResource.GetAllVersionsAsync(
            packageId,
            cache,
            logger,
            CancellationToken.None);
    
        foreach (var version in versions)
        {
            Console.WriteLine($"Found version {version}");
        }
    }
    

    More

    你可以使用 nuget sdk 方便的實現 nuget 包的下載安裝,內部實現了簽名校驗等,這樣就可以把本地不存在的 nuget 包下載到本地了,

    實現示例:

    {
        var pkgDownloadContext = new PackageDownloadContext(cache);
        var downloadRes = await repository.GetResourceAsync<DownloadResource>();
    
        var downloadResult = await RetryHelper.TryInvokeAsync(async () =>
            await downloadRes.GetDownloadResourceResultAsync(
                new PackageIdentity(packageId, packageVersion),
                pkgDownloadContext,
                @"C:\Users\liweihan\.nuget\packages", // nuget globalPackagesFolder
                logger,
                CancellationToken.None), r => true);
        Console.WriteLine(downloadResult.Status.ToString());
    }
    

    最後提供一個解析 nuget globalPackagesFolder 的兩種思路:

    一個是前面有篇文章介紹的,有個默認的配置文件,然後就是默認的配置,寫了一個解析的方法示例,支持 Windows/Linux/Mac:

    {
        var packagesFolder = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
    
        if (string.IsNullOrEmpty(packagesFolder))
        {
            // Nuget globalPackagesFolder resolve
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var defaultConfigFilePath =
                    $@"{Environment.GetEnvironmentVariable("APPDATA")}\NuGet\NuGet.Config";
                if (File.Exists(defaultConfigFilePath))
                {
                    var doc = new XmlDocument();
                    doc.Load(defaultConfigFilePath);
                    var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                    if (node != null)
                    {
                        packagesFolder = node.Attributes["value"]?.Value;
                    }
                }
    
                if (string.IsNullOrEmpty(packagesFolder))
                {
                    packagesFolder = $@"{Environment.GetEnvironmentVariable("USERPROFILE")}\.nuget\packages";
                }
            }
            else
            {
                var defaultConfigFilePath =
                    $@"{Environment.GetEnvironmentVariable("HOME")}/.config/NuGet/NuGet.Config";
                if (File.Exists(defaultConfigFilePath))
                {
                    var doc = new XmlDocument();
                    doc.Load(defaultConfigFilePath);
                    var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                    if (node != null)
                    {
                        packagesFolder = node.Attributes["value"]?.Value;
                    }
                }
    
                if (string.IsNullOrEmpty(packagesFolder))
                {
                    defaultConfigFilePath = $@"{Environment.GetEnvironmentVariable("HOME")}/.nuget/NuGet/NuGet.Config";
                    if (File.Exists(defaultConfigFilePath))
                    {
                        var doc = new XmlDocument();
                        doc.Load(defaultConfigFilePath);
                        var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                        if (node != null)
                        {
                            packagesFolder = node.Value;
                        }
                    }
                }
    
                if (string.IsNullOrEmpty(packagesFolder))
                {
                    packagesFolder = $@"{Environment.GetEnvironmentVariable("HOME")}/.nuget/packages";
                }
            }
        }
    
        Console.WriteLine($"globalPackagesFolder: {packagesFolder}");
    }
    

    另一個是可以根據 nuget 提供的一個命令查詢 nuget locals global-packages -l,通過命令輸出獲取

    Reference

    • https://github.com/WeihanLi/SamplesInPractice/blob/master/NugetSample/RawApiSample.cs
    • https://github.com/WeihanLi/SamplesInPractice/blob/master/NugetSample/NugetClientSdkSample.cs
    • https://docs.microsoft.com/en-us/nuget/reference/nuget-client-sdk
    • https://docs.microsoft.com/en-us/nuget/create-packages/set-package-type
    • https://docs.microsoft.com/en-us/nuget/api/overview
    • https://docs.microsoft.com/en-us/nuget/api/search-autocomplete-service-resource

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

    【【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

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

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

  • Python 簡明教程 — 20,Python 類中的屬性與方法

    Python 簡明教程 — 20,Python 類中的屬性與方法

    微信公眾號:碼農充電站pro
    個人主頁:https://codeshellme.github.io

    與客戶保持良好的關係可以使生產率加倍。
    —— Larry Bernstain

    目錄

    類中的變量稱為屬性,類中的函數稱為方法

    類中的屬性分為:

    • 實例屬性:對象所有,互不干擾
    • 類屬性:類所有,所有對象共享

    類中的方法分為:

    • 實例方法:定義中有self 參數
    • 類方法:定義中有cls 參數,使用@classmethod 裝飾器
    • 靜態方法:定義中即沒有self 參數,也沒有cls 參數,使用@staticmethod 裝飾器

    1,實例屬性與類屬性

    類的對象,就是類的一個實例。類的實例屬性被對象所有,包含在每個對象之中,不同的對象之間,互不干擾。類的類屬性被類所有,被包含在類中,是所有的類對象共享。

    一般情況下,實例屬性會在__init__ 方法中聲明並初始化,並且使用self 來綁定。而類屬性是在類作用域中被聲明,並且不使用self 來綁定。

    例如下面代碼中,country 為類屬性,__name 為實例屬性:

    #! /usr/bin/env python3
    
    class People:
    
        country = 'china'
    
        def __init__(self, name):
            self.__name = name
    

    訪問實例屬性時使用對象.屬性名的格式,實例屬性屬於對象各自的,互不影響:

    >>> p1 = People('小明')
    >>> p2 = People('小美')
    >>> 
    >>> p1.get_name()
    '小明'
    >>> p2.get_name()
    '小美'
    

    類屬性被所有對象共有,一旦被改變,所有對象獲取到的值都會被改變。訪問類屬性時使用類名.屬性名的格式,也可以使用對象.屬性名的格式來訪問:

    >>> People.country              # 用`類名.屬性名`的格式訪問
    'CHINA'
    >>> p1.country                  # 用`對象.屬性名`的格式訪問
    'china'
    >>> p2.country
    'china'
    >>> 
    >>> People.country = 'CHINA'    # 類屬性的值被改變
    >>> p1.country                  # 每個對象獲取到的值也會被改變
    'CHINA'
    >>> p2.country
    'CHINA'
    

    注意,在使用對象.屬性名的格式訪問對象時,不要以這種格式對類屬性進行賦值,否則結果可能不會像你想象的一樣:

    >>> p1 = People('小明')
    >>> p2 = People('小美')
    >>> People.country
    'china'
    >>> p1.country
    'china'
    >>> p2.country
    'china'
    >>> p1.country = '中國'   # 使用`對象.屬性名`的格式對類對象進行賦值
    >>> p1.country           # 只有 p1.country 被改變
    '中國'
    >>> p2.country           # p2.country 沒有被改變
    'china'
    >>> People.country       # People.country 也沒有被改變
    'china'
    

    從上面代碼中可以看到,在Python 中以對象.屬性名格式對類屬性進行賦值時,只有p1.country 的值被改變了,p2.countryPeople.country 的值都沒有被改變。

    實際上,這種情況下,類屬性的值並沒有被改變,而是對象p1 中多了一個country 實例屬性,此後,p1.country 訪問的是p1 的實例屬性,p1.country對屬性country的訪問屏蔽了類中的country屬性,而p2.countryPeople.country 訪問的依然是原來的類屬性

    所以,類名.屬性名對象.屬性名的格式都可以訪問類屬性的值,但盡量避免使用對象.屬性名的格式對類屬性的值進行賦值,否則可能會發生混亂。

    建議:

    不管是訪問還是改變類屬性的值,都只用類名.屬性名的格式

    2,實例方法,類方法,靜態方法

    Python 類中有三種方法:

    • 實例方法
    • 類方法
    • 靜態方法

    實例方法屬於對象,方法中都有一個self 參數(代表對象本身)。實例方法只能由對象調用,不能通過類名訪問。實例方法中可以訪問實例屬性和類屬性。

    類方法屬於類,方法中都有一個cls 參數(代表類本身)。類方法即可以通過類名訪問,也可以通過對象訪問,類方法中只能訪問類屬性,不能訪問實例屬性。

    注意:

    Python 解釋器在構造類與對象時,是先於對象產生的。

    因此,類屬性與類方法是先於實例屬性與實例方法 產生的。

    所以當類方法產生時,還沒有實例屬性,因此,類方法中不能訪問實例屬性。

    靜態方法中,沒有self 參數,也沒有cls 參數。因此,在靜態方法中,即不能訪問類屬性,也不能訪問實例屬性。靜態方法可以使用類名訪問,也可以使用對象訪問。

    在Python 中,定義類方法需要用到裝飾器@classmethod,定義靜態方法需要用到裝飾器@staticmethod

    實例方法演示

    #! /usr/bin/env python3
    
    class People:
    
        country = 'china'
    
        def __init__(self, name):
            self.__name = name
    
        # 實例方法中有self 參數
        def instance_method_test(self):
            # 在實例方法中訪問了實例屬性和類屬性
            print('name:%s country:%s' % (self.__name, People.country))
    

    使用:

    >>> p = People('小明')
    >>> p.instance_method_test()
    name:小明 country:china
    

    在實例方法中訪問了實例屬性__name和類屬性country,均可以被訪問。

    類方法演示

    #! /usr/bin/env python3
    
    class People:
    
        country = 'china'
    
        def __init__(self, name):
            self.__name = name
    
        # 類方法中都有cls 參數
        @classmethod
        def class_method_test1(cls):
            print('在類方法中訪問類屬性country:%s' % cls.country)
    
        @classmethod
        def class_method_test2(cls):
            print('在類方法中訪問實例屬性__name:%s' % self.__name)
    

    使用:

    >>> p = People('小明')
    >>> p.class_method_test1()         # 在類方法中訪問類屬性,可以
    在類方法中訪問類屬性country:china
    >>>
    >>> p.class_method_test2()         # 在類方法中訪問實例屬性,出現異常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/wp/to_beijing/People.py", line 18, in class_method_test2
        print('在類方法中訪問實例屬性__name:%s' % self.__name)
    NameError: name 'self' is not defined
    

    從上面代碼中可以看到,在類方法中可以訪問類屬性,但在類方法中訪問實例屬性,會出現異常。

    靜態方法演示

    #! /usr/bin/env python3
    
    class People:
    
        country = 'china'
    
        def __init__(self, name):
            self.__name = name
    
        # 靜態方法中即沒有self 參數也不沒有cls 參數
        @staticmethod
        def static_method_test1():
            print('在靜態方法中訪問類屬性country:%s' % cls.country)
    
        @staticmethod
        def static_method_test2():
            print('在靜態方法中訪問實例屬性__name:%s' % self.__name)
    

    使用:

    >>> p = People('小明')
    >>> p.static_method_test1()      # 在靜態方法中訪問類屬性,出現異常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/wp/to_beijing/People.py", line 14, in static_method_test1
        print('在靜態方法中訪問類屬性country:%s' % cls.country)
    NameError: name 'cls' is not defined
    >>>
    >>> p.static_method_test2()     # 在靜態方法中訪問實例屬性,出現異常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/wp/to_beijing/People.py", line 18, in static_method_test2
        print('在靜態方法中訪問實例屬性__name:%s' % self.__name)
    NameError: name 'self' is not defined
    

    從上面代碼中可以看到,在靜態方法中無論訪問實例方法還是類方法,都會出現異常。

    3,專有方法

    我們之前講到過的魔法方法,即以雙下劃線__開頭且結尾的方法__xxx__,就是專有方法。這些方法都被Python 賦予了特殊的含義,用戶可以根據需要,來實現這些方法。

    下面我們介紹一些 Python 中常見的專有方法。

    __len__ 方法

    實現該方法的類的對象,可以用len() 函數計算其長度。

    __str__ 方法

    實現該方法的類的對象,可以轉化為字符串。

    __call__ 方法

    實現該方法的類的對象,可以像函數一樣調用。

    __iter__ 方法

    實現該方法的類的對象,是可迭代的。

    __setitem__ 方法

    實現該方法的類的對象,可以用索引的方式進行賦值。

    __getitem__ 方法

    實現該方法的類的對象,可以用索引的方式進行訪問。

    __contains__ 方法

    實現該方法的類的對象,可以進行in 運算。

    __add__ 方法

    實現該方法的類的對象,可以進行加+運算。

    __sub__ 方法

    實現該方法的類的對象,可以進行減-運算。

    __mul__ 方法

    實現該方法的類的對象,可以進行乘*運算。

    __div__ 方法

    實現該方法的類的對象,可以進行除/運算。

    __pow__ 方法

    實現該方法的類的對象,可以進行乘方運算。

    __mod__ 方法

    實現該方法的類的對象,可以進行取模運算。

    __eq__ 方法

    實現該方法的類的對象,可以進行相等==比較。

    __ne__ 方法

    實現該方法的類的對象,可以進行不等於!=比較。

    __gt__ 方法

    實現該方法的類的對象,可以進行大於>比較。

    __ge__ 方法

    實現該方法的類的對象,可以進行大於等於>=比較。

    __lt__ 方法

    實現該方法的類的對象,可以進行小於<比較。

    __le__ 方法

    實現該方法的類的對象,可以進行小於等於<=比較。

    (完。)

    推薦閱讀:

    Python 簡明教程 — 15,Python 函數

    Python 簡明教程 — 16,Python 高階函數

    Python 簡明教程 — 17,Python 模塊與包

    Python 簡明教程 — 18,Python 面向對象

    Python 簡明教程 — 19,Python 類與對象

    歡迎關注作者公眾號,獲取更多技術乾貨。

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案