Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲视频欧洲视频,欧美激情_区二区三区,在线观看视频你懂得

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          PEP8(二),命名風(fēng)格

          PEP8(二),命名風(fēng)格

          一種編程語言,都有以下概念:

          • 變量;
          • 函數(shù)或者方法;
          • 類;
          • 模塊;

          都有許多需要程序員命名的地方。

          不同的語言,命名規(guī)范各不相同。

          對Python來說,PEP8推薦的命名規(guī)范如下(此處基于Effective Python書中列舉的條目整理,PEP8標(biāo)準(zhǔn)中會更詳細些,筆者建議大家可以簡單過一遍PEP8文檔):

          1、函數(shù)名、變量名、屬性名

          用小寫字母配下劃線,例如lowercase_underscore

          2、類對象的屬性

          類對象的屬性(attributes,筆者會更習(xí)慣使用“成員變量”這個詞)和保護變量由變量名前方的下劃線數(shù)量決定,一個下劃線是保護變量(_protect_value),兩個下劃線是私有變量(__private_value)。

          筆者在此處有一個慚愧測試:我印象中Python類對象的屬性即便用雙下劃線開頭,也是可以直接訪問的。

          寫本篇博客時在Python3.10.2和2.7.18中測試,發(fā)現(xiàn)自己的記憶是錯誤的:直接訪問雙下劃線變量,會拋出AttributeError異常,Python是有做私有變量的訪問限制的。

          # tmp.py
          class Xx(object):
              def __init__(self):
                  self._x=9
                  self.__xx=10
          
              def getXX(self):
                  return self.__xx
          
          
          if __name__=='__main__':
              x=Xx()
              print(x._x)
              print(x.getXX())
              print(x.__xx)
          
          # 在Python2中的測試(Python3當(dāng)中是一樣的)
          > py -2 tmp.py
          9
          10
          Traceback (most recent call last):
            File "tmp.py", line 30, in <module>
              print(x.__xx)
          AttributeError: 'Xx' object has no attribute '__xx'
          

          筆者近一年的工作中,寫Python很少(這也是筆者去年放棄錄制視頻的原因之一),寫C++較多。當(dāng)筆者寫本篇筆記時,好奇C++是否有相同的規(guī)范供借鑒,便搜一下C++的命名規(guī)范,其中排名最靠前的,是谷歌版本的C++代碼規(guī)范。

          Google C++ Style Guide:

          https://google.github.io/styleguide/cppguide.html

          由此推理,Python肯定也有谷歌版本的編碼風(fēng)格存在的。

          Google Python Style Guide:

          https://google.github.io/styleguide/pyguide.html

          筆者看了下谷歌的命名規(guī)范,發(fā)現(xiàn)谷歌的程序員們并不推薦使用雙下劃線作為變量名稱,即便Python自己做了“訪問限制”。

          由此,筆者再發(fā)現(xiàn)一個之前從未聽過的概念:name mangling。(待去搜一下,發(fā)現(xiàn)不知道的只是名詞“name mangling”,它的另一個名字是“名字裝飾”,筆者的理解是:編譯器為防止代碼中的變量重復(fù),會在編譯時將這些變量加一些額外內(nèi)容以做差異化。)

          維基百科對name mangling的解釋:

          https://zh.m.wikipedia.org/wiki/%E5%90%8D%E5%AD%97%E4%BF%AE%E9%A5%B0

          筆者有對Python中的name mangling做一下測試:

          class Demo:
              any_name='any_name'
              _any_name='_any_name'
              __any_name='__any_name'
          
              def __init__(self):
                  self.__any_x='__any_x'
                  self._any_y='_any_y'
          
          class Demo2:
              any_name='any_name'
              _any_name='_any_name'
              __any_name='__any_name'
          
          
          # 測試一下多繼承(注:Python雖然支持多繼承,但并不推薦)
          class Child(Demo, Demo2):
              pass
          
          
          if __name__=='__main__':
              for n in dir(Demo):
                  if('any' in n):
                      print('cls ->', n)
          
              print('-------------------------')
          
              demo=Demo()
              for n in dir(demo):
                  if('any' in n):
                      print('object ->', n)
          
              print('Python并不能真正的做到成員私有:', demo._Demo__any_x)
          
              print('-------------------------')
          
              for n in dir(Child):
                  if('any' in n):
                      print('child ->', n)
                      
          

          測試結(jié)果如下:

          > python3 tmp.py
          # name mangling,加雙下劃線的變量名加上了類名前綴
          cls -> _Demo__any_name
          cls -> _any_name
          cls -> any_name
          -------------------------
          object -> _Demo__any_name
          object -> _Demo__any_x  # 對象中的name mangling
          object -> _any_name
          object -> _any_y
          object -> any_name
          Python并不能真正的做到成員私有: __any_x
          -------------------------
          # 多繼承在這里,被區(qū)分出來
          child -> _Demo2__any_name
          child -> _Demo__any_name
          # 但是重復(fù)的變量名,最后只剩一個(筆者未來的更新中會和大家一起討論這個問題)
          child -> _any_name
          child -> any_name
          

          由以上測試,我理解了為什么谷歌文檔中說“沒有真正實現(xiàn)私有”:雙下劃線變量,改一下名字就可以訪問了。

          3、類名

          類名應(yīng)該用首字母大寫的駝峰模式:

          class CapitalizedWord:
              pass
          

          4、模塊化常量

          模塊化常量使用全部大寫形式,單詞間用下劃線分開。

          THIS_IS_A_CONST_VALUE=10
          

          5、類實例函數(shù)

          類實例的第一個參數(shù)應(yīng)該用self開頭。

          class MyTmpCls(object):
              def __init__(self, val):
                  self._value=val
          

          6、類方法

          類方法的第一個參數(shù),使用cls,表示這是類本身。

          筆者曾經(jīng)在某一次面試當(dāng)中被要求手寫Python版本的單例,當(dāng)時沒寫出來。筆者的借口是:過去單例的使用,都是從網(wǎng)上抄錄下來的。

          筆者于此處抄一個簡單單例在此處,供大家參考也供筆者自己記錄。它來自于Stack Overflow:

          class Singleton(object):
              _instance=None
          
              def __init__(self, *args, **kwargs):
                  print('this is the init func.', id(self))
          
              def __new__(cls, *args, **kwargs):
                  if not cls._instance:
                      cls._instance=super().__new__(cls, *args, **kwargs)
                  return cls._instance
          
          
          a=Singleton()
          b=Singleton()
          print(a is b)  # True
          

          筆者最喜歡的程序員社區(qū)網(wǎng)站是Stack Overflow,它專業(yè)、全面且干凈,筆者在遇到搞不定問題時,最先想到的便是到Stack Overflow去看看是否有前人遇見過相似問題。

          絕大部分情況下,是有前人遇見過相似問題的。筆者整理本篇博客時,又去該網(wǎng)站上看了下前人對Python當(dāng)中命名規(guī)范的討論,我找到一個算是很火的帖子,這帖子中主要關(guān)注的關(guān)鍵字有兩個:PEP8谷歌標(biāo)準(zhǔn)

          由此,本篇博客以對谷歌標(biāo)準(zhǔn)的摘抄作為結(jié)束:

          The Google Python Style Guide has the following convention:

          module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_CONSTANT_NAME, global_var_name, instance_var_name, function_parameter_name, local_var_name.

          谷歌推薦的Python編碼標(biāo)準(zhǔn)原文鏈接如下:

          英文:https://google.github.io/styleguide/pyguide.html#316-naming

          中文:https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules.html#id15

          筆者寫本篇時,再次感覺到之前已經(jīng)總結(jié)過的感受:每一項技能,如果深入進去,是都有許多內(nèi)容可以輸出的。

          本篇博客,對命名規(guī)范的討論肯定并不全面。不過筆者的觀點依然是:我們寫代碼,在讓機器正確執(zhí)行前提下,是需要考慮可讀性的。

          如何提升可讀性?保持統(tǒng)一的命名風(fēng)格,會有幫助。

          SS標(biāo)準(zhǔn)化設(shè)計命名:

          1、類class的命名規(guī)范示例

          頭:header

          內(nèi)容:content/container

          尾:footer

          導(dǎo)航:nav 

          側(cè)欄:sidebar

          欄目:column  

          頁面外圍控制整體布局寬度:wrapper  

          左右中:left right center  

          登錄條:loginbar  

          標(biāo)志:logo  

          廣告:banner  

          頁面主體:main  

          熱點:hot  

          新聞:news  

          下載:download  

          子導(dǎo)航:subnav  

          菜單:menu  

          子菜單:submenu  

          搜索:search  

          友情鏈接:friendlink  

          頁腳:footer  

          版權(quán):copyright  

          滾動:scroll  

          內(nèi)容:content  

          標(biāo)簽頁:tab  

          文章列表:list  

          提示信息:msg  

          小技巧:tips  

          欄目標(biāo)題:title  

          加入:joinus  

          指南:guild  

          服務(wù):service  

          注冊:regsiter  

          狀態(tài):status  

          投票:vote  

          合作伙伴:partner

          2、注釋的寫法  

          / Footer /  

          內(nèi)容區(qū)  

          / End Footer /

          3、id的命名規(guī)范示例

          (1)頁面結(jié)構(gòu)

            容器: container

            頁頭:header

            內(nèi)容:content/container

            頁面主體:main

            頁尾:footer

            導(dǎo)航:nav

            側(cè)欄:sidebar

            欄目:column

            頁面外圍控制整體布局寬度:wrappe

          左右中:left right center

          (2)導(dǎo)航

            導(dǎo)航:nav

            主導(dǎo)航:mainbav

            子導(dǎo)航:subnav

            頂導(dǎo)航:topnav

            邊導(dǎo)航:sidebar

            左導(dǎo)航:leftsidebar

            右導(dǎo)航:rightsidebar

            菜單:menu

            子菜單:submenu

            標(biāo)題: title

            摘要: summary 

           (3)功能

            標(biāo)志:logo

            廣告:banner

            登陸:login

            登錄條:loginbar

            注冊:regsiter

            搜索:search

            功能區(qū):shop

            標(biāo)題:title

            加入:joinus

            狀態(tài):status

            按鈕:btn

            滾動:scroll

            標(biāo)簽頁:tab

            文章列表:list

            提示信息:msg

            當(dāng)前的: current

            小技巧:tips

            圖標(biāo): icon

            注釋:note

            指南:guild

            服務(wù):service

            熱點:hot

            新聞:news

            下載:download

            投票:vote

            合作伙伴:partner

            友情鏈接:link

            版權(quán):copyright

          4、類class的書寫規(guī)范示例

            (1)顏色:使用顏色的名稱或者16進制代碼,如

            .red { color: red; }

            .f60 { color: #f60; }

            .ff8600 { color: #ff8600; }

           (2)字體大小,直接使用"font+字體大小"作為名稱,如

            .font12px { font-size: 12px; }

            .font9pt {font-size: 9pt; }

           (3)對齊樣式,使用對齊目標(biāo)的英文名稱,如

            .left { float:left; }

            .bottom { float:bottom; }

           (4)標(biāo)題欄樣式,使用"類別+功能"的方式命名,如

            .barnews { }

            .barproduct { }

          5、CSS文件命名示例

            主要的 master.css

            模塊 module.css

            基本共用 base.css

            布局,版面 layout.css

            主題 themes.css

            專欄 columns.css

            文字 font.css

            表單 forms.css

            補丁 mend.css

            打印 print.css6、注意事項

            (1)一律小寫;

            (2)盡量用英文;

            (3)不加中杠和下劃線;

            (4)盡量不縮寫,除非一看就明白的單詞。

          擊右上方紅色按鈕關(guān)注“web秀”,讓你真正秀起來

          前言

          以往我們只是習(xí)慣于通過數(shù)組下標(biāo)來訪問正則匹配到的分組,但分組達到4、5個時,標(biāo)識起來就會非常麻煩。V8早已實現(xiàn)了正則命名分組提案,只是我們很少使用,本文將介紹JS的正則命名分組。

          JavaScript 正則命名分組

          過去

          假設(shè)要使用正則匹配一個日期的年月日,以往我們會這樣做:

          const RE_DATE=/(\d{4})-(\d{2})-(\d{2})/;
          
          const matchObj=RE_DATE.exec('1999-12-31');
          const year=matchObj[1]; // 1999
          const month=matchObj[2]; // 12
          const day=matchObj[3]; // 31
          

          這里有幾個缺點:

          • 要找到一個分組的位置,你必須要去數(shù)括號的位置,有時嵌套起來會更令人頭疼。
          • 后面維護代碼的同學(xué)閱讀起來,還要根據(jù)下標(biāo)找到正則里面對應(yīng)的括號,并且要再次閱讀括號里面的正則才知道含義。
          • 當(dāng)你調(diào)整正則捕獲分組的數(shù)量、順序或嵌套時,你必要還要對下面的代碼做調(diào)整。

          所有這些問題,都可以通過正則命名分組來解決。

          現(xiàn)在

          現(xiàn)在你只需要給分組里面一個命名標(biāo)識即可:

          (?<year>\d{4})
          

          這里,我們用變量year標(biāo)記了上一個捕獲組#1。 該名稱必須是合法的JavaScript標(biāo)識符。 匹配后,您可以通過matchObj.groups.year訪問捕獲的字符串。

          讓我們通過命名分組重寫前面的代碼:

          const RE_DATE=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
          
          const matchObj=RE_DATE.exec('1999-12-31');
          const year=matchObj.groups.year; // 1999
          const month=matchObj.groups.month; // 12
          const day=matchObj.groups.day; // 31
          

          如果正則里面有了命名分組,那么匹配結(jié)果會多了一個groups 的屬性,這個屬性中包含了一切命名分組的捕獲結(jié)果。配合上解構(gòu)大法使用又是一股清流:

          const {groups: {day, year}}=RE_DATE.exec('1999-12-31');
          console.log(year); // 1999
          console.log(day); // 31
          

          當(dāng)然,即使你使用了命名分組,那么返回的結(jié)果還可以通過以往的數(shù)組下標(biāo)方式訪問:

          const year2=matchObj[1]; // 1999
          const month2=matchObj[2]; // 12
          const day2=matchObj[3]; // 31
          

          命名分組具有以下優(yōu)點:

          • 找到分組的“ID”更容易。
          • 匹配的代碼變得自描述性,因為分組的ID描述了捕獲的內(nèi)容。
          • 如果更改分組的順序,則不必更改匹配的代碼。
          • 分組的名稱也使正則表達式更易于理解,因為您可以直接看到每個組的用途。

          反向引用

          反向引用命名分組\k<name> 看下面這個匹配重復(fù)單詞的例子:

          const RE_TWICE=/^(?<word>[a-z]+)!\k<word>$/;
          RE_TWICE.test('abc!abc'); // true
          RE_TWICE.test('abc!ab'); // false
          

          同時也可以使用以往的反向引用方式:

          const RE_TWICE=/^(?<word>[a-z]+)!\1$/;
          RE_TWICE.test('abc!abc'); // true
          RE_TWICE.test('abc!ab'); // false
          

          replace( )

          字符串方法replace()以兩種方式支持命名分組:

          方式一

          const RE_DATE=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
          console.log('1999-12-31'.replace(RE_DATE, '$<month>/$<day>/$<year>'));
          // 12/31/1999
          

          如果replace不一定是直接返回新的拼接字符串,那么可以看看下面的辦法:

          方式二

          const RE_DATE=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
          console.log('1999-12-31'.replace(
           RE_DATE,
           (g, y, m, d, offset, input, {year, month, day})=>
           month+'/'+day+'/'+year));
           // 12/31/1999
          

          看看這replace的callback形參密密麻麻看得心慌慌,很多都用不上,那么我們看看更簡單的寫法:

          console.log('1999-12-31'.replace(RE_DATE,
           (...args)=> {
           const {year, month, day}=args.slice(-1)[0];
           return month+'/'+day+'/'+year;
           }));
           // 12/31/1999
          

          這里配合上spread operator直取最后一個參數(shù),再接上一個解構(gòu)大法,結(jié)果又是一股清流。

          命名分組沒有匹配結(jié)果?

          如果可選的命名組不被匹配,則其屬性值被設(shè)置為undefined,但key是仍存在:

          const RE_OPT_A=/^(?<as>a+)?$/;
          const matchObj=RE_OPT_A.exec('');
          
          // We have a match:
          console.log(matchObj[0]===''); // true
          
          // Group <as> didn’t match anything:
          console.log(matchObj.groups.as===undefined); // true
          
          // But property as exists:
          console.log('as' in matchObj.groups); // true
          

          異常情況

          分組名不能有重復(fù)項:

          /(?<foo>a)(?<foo>b)/ // SyntaxError: Duplicate capture group name
          

          反向引用一個不存在的分組名:

          /\k<foo>/u // SyntaxError: Invalid named capture referenced
          /\k<foo>/.test("k<foo>") // true, 非 Unicode 下為了向后兼容,k 前面的 \ 會被丟棄
          

          在 reaplce() 方法的替換字符串中引用一個不存在的分組:

          "abc".replace(/(?<foo>.*)/, "$<bar>") // SyntaxError: Invalid replacement string
          "abc".replace(/(.*)/, "$<bar>") // "$<bar>",不包含命名分組時會向后兼容
          

          說明

          Chrome60 已支持命名分組 通過babel插件處理兼容問題 babel-plugin-transform-modern-regexp

          公告

          喜歡小編的點擊關(guān)注,了解更多知識!


          主站蜘蛛池模板: 中文字幕在线观看一区二区| 国产福利91精品一区二区三区| 国产美女av在线一区| 久久精品无码一区二区三区 | 国产无吗一区二区三区在线欢| 狠狠爱无码一区二区三区| 一级特黄性色生活片一区二区| 国产成人精品一区二区三在线观看| 无码喷水一区二区浪潮AV| 日韩精品国产一区| 亚洲视频在线一区二区| 国产成人无码AV一区二区| 无码精品人妻一区二区三区漫画 | 无码人妻久久一区二区三区蜜桃 | 国产一区二区三区樱花动漫| 精品视频一区二区三区| 亚洲天堂一区二区三区| 四虎在线观看一区二区| 高清国产精品人妻一区二区| 亚洲熟女综合一区二区三区| 一区二区免费在线观看| 精品国产乱码一区二区三区| 国产激情一区二区三区四区| 日本大香伊一区二区三区| 色窝窝免费一区二区三区| 精品国产亚洲一区二区在线观看 | 精品久久久久久中文字幕一区| 国产日韩AV免费无码一区二区三区| 久久精品岛国av一区二区无码| 无码人妻精一区二区三区| 国产一区二区免费| 国产成人精品无码一区二区老年人| 久久精品一区二区三区不卡| 在线精品自拍亚洲第一区| 国产激情无码一区二区app| 日本在线视频一区二区三区| 亚洲一区二区三区四区在线观看| 国产精品一区二区久久沈樵| 亚洲制服丝袜一区二区三区| 中文字幕无码一区二区三区本日| 国产精品无码一区二区在线观 |