<tbody id="fuft6"><noscript id="fuft6"><video id="fuft6"></video></noscript></tbody>
    <tbody id="fuft6"><noscript id="fuft6"></noscript></tbody>
    <em id="fuft6"><acronym id="fuft6"></acronym></em>
          <button id="fuft6"><acronym id="fuft6"><u id="fuft6"></u></acronym></button>
          首頁人工智能技術資訊正文

          如何成為頂級開源項目的貢獻者

          更新時間:2020-09-07 來源:黑馬程序員 瀏覽量:

          概述

          對于程序員來講,成為頂級開源項目的貢獻者是一件有意義的事,當然,這也絕非易事。如果你正從事人工智能有關的工作,那么你一定了解諸如Google Tensorflow,Facebook Pytorch這樣的開源項目。下面我們就說一說如何成為這些頂級的開源項目的Contributor。

          準備

          1.首先你必須成為github的使用者,并已經熟悉了github上托管代碼的基本邏輯。

          2.對于頂級的開源項目,一般需要你去簽署一份Contributor License Agreement(簡稱CLA),例如Tensorflow項目,個人簽署TF individual CLA,公司簽署TF corporate CLA,Pytorch中的部分項目則需要簽署Facebook CLA,這樣你的代碼才允許被接收。

          3.讓你編寫的代碼風格更規范,一般的開源項目都要求為Google Python Style,即使是Pytorch都是遵循該規范,更不要說Google自家的Tensorflow了。

          4.你貢獻的代碼往往由類或者函數構成(文檔貢獻除外),因此你需要單元測試程序,它和代碼注釋一樣,是代碼共享過程中必不可少的一部分。沒有它,即使你的代碼正確無誤也不會被merge,最終還是會被要求提供單元測試腳本。

          5.很多開源項目要求你的每個py腳本都要以許可證書開頭,比如Tensorflow,這是它的python許可證書示例: Python license example,當然,這很簡單。

          # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
          #
          # Licensed under the Apache License, Version 2.0 (the "License");
          # you may not use this file except in compliance with the License.
          # You may obtain a copy of the License at
          #
          #     http://www.apache.org/licenses/LICENSE-2.0
          #
          # Unless required by applicable law or agreed to in writing, software
          # distributed under the License is distributed on an "AS IS" BASIS,
          # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          # See the License for the specific language governing permissions and
          # limitations under the License.
          # =============================================================================

          工具

          接下來我們將介紹相關工具的使用,它能夠有效的幫助我們來完成貢獻前的準備工作,比如:代碼規范和單元測試等。

          代碼規范工具

          為了滿足代碼滿足Google Style的要求,我們首先需要一個代碼規范檢測工具,這里我們使用官方推薦的pylint。

          安裝:

          pip install pylint

          使用:
          # 使用pylint檢測腳本代碼,默認將按照PEP8標準
          # 這里我們需要指定配置文件,即按照Google Style標準
          # myfile.py代表你寫好的python腳本文件
          pylint --rcfile=pylintrc myfile.py

          pylintrc內容請參照: pylintrc

          又因為我們初始寫的代碼往往隨意性過強,可能直接用pylint需要修改的地方太多,可能對你幼小的心靈造成重創,因此,這里也帶來很多開源項目推薦的另外一款工具:black,它能夠直接幫你修改代碼中出現的基本問題(仍然存在很多問題無法被判定,需要使用pylint檢測)。

          安裝:

          pip install black


          使用:
          # 這里的-l代表代碼的每行最大長度
          # 默認是88,但是Google Style要求為80
          # 因此這里指定為80
          black myfile.py -l 80


          代碼樣式示例:

          def my_op(tensor_in, other_tensor_in, my_param, other_param=0.5,
                    output_collections=(), name=None):
            """My operation that adds two tensors with given coefficients.
          
            Args:
              tensor_in: `Tensor`, input tensor.
              other_tensor_in: `Tensor`, same shape as `tensor_in`, other input tensor.
              my_param: `float`, coefficient for `tensor_in`.
              other_param: `float`, coefficient for `other_tensor_in`.
              output_collections: `tuple` of `string`s, name of the collection to
                                  collect result of this op.
              name: `string`, name of the operation.
          
            Returns:
              `Tensor` of same shape as `tensor_in`, sum of input values with coefficients.
          
            Example:
              >>> my_op([1., 2.], [3., 4.], my_param=0.5, other_param=0.6,
                        output_collections=['MY_OPS'], name='add_t1t2')
              [2.3, 3.4]
            """
            with tf.name_scope(name or "my_op"):
              tensor_in = tf.convert_to_tensor(tensor_in)
              other_tensor_in = tf.convert_to_tensor(other_tensor_in)
              result = my_param * tensor_in + other_param * other_tensor_in
              tf.add_to_collection(output_collections, result)
              return result
          output = my_op(t1, t2, my_param=0.5, other_param=0.6,
                         output_collections=['MY_OPS'], name='add_t1t2')


          單元測試工具

          ·單元測試對于團隊開發十分重要,是檢驗代碼質量的重要依據,因此你的每一份完整的代碼都要配備單元測試腳本。這里我們使用python主流的單元測試工具unittest。

          · 安裝:

          pip install unittest


          使用: 這里只去演示核心的使用方法,更具體的內容請參照unittest文檔

          # 導入unittest工具包
          import unittest
          
          # 我們首先要建立一個測試類,它將包含你所有需要進行測試的函數
          # 這個類不使用__init__(self),但可以使用setUp(self)來定義公有部分
          # 它需要繼承unittest.TestCase, 類名往往也建議以Test開頭
          class TestStringMethods(unittest.TestCase):
              # 類的里面依次是你需要進行測試的函數
              # 這些函數建議以test_開頭
              # 這些函數一般情況不設置參數,而是直接在函數中具體化需要的參數
              # 當然你也可以設置原始的參數,然后在外部具體化參數并調用該函數
              # 在測試函數中必須存在assert...來斷定測試結果
              # 常用的assert...包括: assertEqual, assertTrue, assertFalse,
              # assertRaises, assertIn, assertNotIn, assertIs, assertIsNot...
              def test_upper(self,):
                  # 使用assertEqual判斷兩個字符串是否相等
                  self.assertEqual(
                      "foo".upper(), "FOO",
                  )
          
              def test_isupper(self,):
                  # 使用assertTrue/False斷定條件為真/假
                  self.assertTrue("FOO".isupper())
                  self.assertFalse("Foo".isupper())
          
              def test_split(self,):
                  # 設定任意輸入
                  s = "hello world"
                  # 使用assertIn斷定列表包含關系
                  self.assertIn(
                      s.split(), [["hello", "world"]],
                  )
                  # 注意:這里with self.assertRaises來斷定異常
                  with self.assertRaises(TypeError):
                      s.split("asd")
          
          
          # 這里是主函數,如果使用python運行該腳本測試,則必須存在
          # 如果使用pytest(后面會介紹),則可以省略
          if __name__ == "__main__":
              # 使用unittest.main運行所有繼承unittest.TestCase的類
              unittest.main()

          裝飾器的使用: unittest最常使用方法之一就是類/函數的裝飾器。

          # 對于一些特殊需要強制跳過的測試的類/函數使用下方裝飾器,但你必須說明原因
          # @unittest.skip("長得太帥,不需要測試,給我跳過!")
          
          # 如果條件為真,則該測試被強制跳過。比如:檢測GPU是否可用
          # @unittest.skipIf(TEST_CUDA, "CUDA available")
          
          # 除非條件為真,否則該測試被強制跳過。比如: 檢測某些依賴包是否安裝
          # @unittest.skipUnless(has_unittest, "unittest dependencies are not installed")
          
          # 函數異常測試的表達方式,函數出現異常則測試通過,比之前說的內部異常粒度更大
          # @unittest.expectedFailure
          
          import torch
          try:
              import unittest
          except ImportError:
              has_unittest = False
          else:
              has_unittest = True
          
          if torch.cuda.is_available():
              TEST_CUDA = True
          else:
              TEST_CUDA = False
          
          # 條件為真,不跳過
          @unittest.skipUnless(has_unittest, "unittest dependencies are not installed")
          # 條件為真,跳過;條件為假,不跳過
          @unittest.skipIf(TEST_CUDA, "CUDA available")
          class TestStringMethods(unittest.TestCase):
              def test_upper(self,):
                  self.assertEqual(
                      "foo".upper(), "FOO",
                  )
              @unittest.skip("長得太帥,不需要測試,給我跳過!")
              def test_isupper(self,):
                  self.assertTrue("FOO".isupper())
                  self.assertFalse("Foo".isupper())
          
              @unittest.expectedFailure
              def test_split(self,):
                  s = "hello world"
                  self.assertIn(
                      s.split(), [["hello", "world"]],
                  )
                  # 這里預計拋出異常,但實際沒有異常,本質上這也算一種異常
                  # 可以使用@unittest.expectedFailure
                  with self.assertRaises(TypeError):
                      s.split("ZMZ")
          
          
          if __name__ == "__main__":
              unittest.main()


          運行你的測試腳本:

          # 建議使用pytest執行測試腳本,你的python中往往自帶這個工具包
          # 這時你不必寫下主函數,并且他的輸出形式更美觀
          pytest test_myfile.py


          輸出效果:

          ======================== test session starts =========================
          platform linux -- Python 3.7.3, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
          rootdir: /root
          plugins: remotedata-0.3.1, celery-4.3.0, doctestplus-0.3.0, arraydiff-0.3, openfiles-0.3.2
          collected 3 items
          
          test_myfile.py sx.                                             [100%]
          
          =========== 1 passed, 1 skipped, 1 xfailed in 0.34 seconds ===========

          真實單元測試腳本請參考Pytorch Tests和Tensorflow Tests

          過程

          在準備成為貢獻者之前,要確保你已經能夠熟練使用該項目。進而明確你要貢獻源碼的類型,是Fix Bug還是Implement New Feature(實現新特性)。當然,對一個新手貢獻者來講,Fix Bug是你的不二選擇。除非你已經通過自己的實踐,明確了要做貢獻的具體內容,否則,建議你需要遵循以下步驟:

          第一步:

          從開源項目的Github Issues中尋找open的問題,這里是Tensorflow Issues, Pytorch Issues,仔細閱讀大家提出的問題,這將幫你在尋找問題上節約大量時間,同時你可以在討論區看到有關技術的討論或已經提交的PR,進一步明確自己是否應該參與該問題的解決。(有很多開源項目的issue會帶有"contributions welcome"的標簽,可以優先看一看。)

          第二步:

          當你明確了自己要解決的問題,在正式寫代碼之前,你需要fork這個開源項目到你自己的Github倉庫,然后再將該倉庫clone到自己指定的服務器上,這樣最后你才可以提交PR。

          # 例如:
          git clone https://github.com/AITutorials/tensorflow.git

          到這里你可以通過git remote -v發現我們只與自己遠程倉庫進行了連接(origin/master)。

          此時我們還需要與開源項目的遠程倉庫建立連接(upstream/master)

          # 以tensorflow為例建立連接
          git remote add upstream https://github.com/tensorflow/tensorflow.git
          
          # 查看到upstream
          git remote -v

          然后你就需要建立一個自己的分支,當然,你可以先查看一下遠程的分支情況

          # 查看遠程分支
          git branch -a
          
          # 創建自己的遠程分支cnsync
          git checkout -b cnsync

          第三步:

          通過第二步你已經拿到了項目的源碼并創建了自己分支,這時就要開始你的表演,coding + review,你之前準備的代碼規范工具和單元測試工具將派上用場。

          第四步:

          提交代碼你的代碼并在github中創建一個PR。

          # 把內容添加到暫存區
          git add .
          
          # 提交更改的內容
          git commit -m "添加你的改變說明"
          
          # push到自己的遠程倉庫
          git push origin cnsync

          注意:這里雖然你只push到了自己的遠程倉庫,但其實你的遠程倉庫和源項目的倉庫是連接的。也就是說,此時你可以通過操作自己的遠程倉庫決定是否將創建一個源項目的PR(這些過程可以在你剛剛fork的項目頁面中實現,包括填寫PR的title和comment,有時你也需要在title中添加一個標記,如[Draft]/[WIP]/[RFR]等等)。

          第五步:

          耐心的等待,如果你是PR是一個Ready For Review的狀態,它將很快進入自動化測試的流程以及評委會的介入,不久后你將收到一些反饋,你的代碼方案可能被采納,可能需要更多的修改或測試。

          結語

          最終,經過不斷地磨練,你將成為一名頂級開源項目的貢獻者,所以,加油吧少年!


          猜你喜歡:

          Bert算法:語言模型-BERT詳細介紹

          孤立森林算法介紹,這次終于看懂了!

          在線咨詢 我要報名
          和我們在線交談!

          黄色网站片

          <tbody id="fuft6"><noscript id="fuft6"><video id="fuft6"></video></noscript></tbody>
            <tbody id="fuft6"><noscript id="fuft6"></noscript></tbody>
            <em id="fuft6"><acronym id="fuft6"></acronym></em>
                  <button id="fuft6"><acronym id="fuft6"><u id="fuft6"></u></acronym></button>