برای مشاهده یافته ها از کلید Enter و برای خروج از کلید Esc استفاده کنید.

داکیومنتِ کد در پایتون قسمت ۲

در قسمت اول داکیومنتِ کد در پایتون در مورد استفاده از docstring خوندیم. در این قسمت میخوایم با استاندارد گوگل برای نوشتن داک‌استرینگ آشنا بشیم.

Module

هر ماژول باید با داک‌استرینگ شروع شود که شامل توضیحاتی در رابطه با محتوای آن ماژول و راهنمای استفاده از آن است.
فرمت داک‌استرینگ ماژول ها به ترتیب خطوط:

  • خلاصه ای یک خطی در مورد ماژول که به . ختم می‌شود(عنوان اصلی)
  • یک خط خالی
  • ادامه توضیحات در رابطه با کارکرد و محتوای ماژول است، که میتواند این توضیحات شامل متدها و کلاس های اکسپورت شده‌ی ماژول و مثال های کوتاهی از آنها باشد.(توضیحات)
"""A one line summary of the module or program, terminated by a period.

Leave one blank line.  The rest of this docstring should contain an
overall description of the module or program.  Optionally, it may also
contain a brief description of exported classes and functions and/or usage
examples.

  Typical usage example:

  foo = ClassFoo()
  bar = foo.FunctionBar()
"""

Function و Method

  • در این قسمت برای راحتی از عبارت فانکشن بجای متد و فانکشن استفاده میکنیم.

هر فانکشن فقط در سه حالت مجاز است که داک‌استرینگ نداشته باشد:

  1. private باشد
  2. خیلی کوتاه باشد
  3. کاملا واضح باشد

داک‌استرینگِ یک فانکشن باید به گونه ای باشه که بدون خوندن کد، بتونیم متوجه بشیم که اون فانکشن رو چطور باید کال کنیم. توضیحات در داک‌استرینگ شامل توضیح در مورد منطق کد است و نه نحوه پیاده سازی.

داک‌استرینگ فانکشن هم مانند ماژول شامل بخش های عنوان اصلی و توضیحات است و علاوه بر این دو بخش شامل ۳ بخش دیگر هم هست که البته همه‌ی آنها الزامی نیست:

Args:
لیست پارامترهای ورودی فانکشن است که به ترتیب از چپ به راست شامل موارد زیر خواهد بود:

  • نام پارامتر
  • :
  • فاصله
  • توضیح در مورد پارامتر (اگر توضیحات بیشتر از یک خط شود خط های بعد از خط اول با ۴ فاصله شروع می‌شوند) در این قسمت نوع پارامتر(مثلا int, string) را هم مشخص میکنیم.

Returns:
در این قسمت نوع و منطق مقدار بازگشتی رو بیان میکنیم. اگر فانکشن مقدار None برگرداند نوشتن این بخش الزامی نیست. ممکن است گاهی در توضیحات خود فانکشن مقدار بازگشتی آن را بنویسیم. در این صورت هم نوشتن این بخش لازم نیست. مثلا

def my_function():
    """Returns row from Bigtable as a tuple of strings.""""

Raises:
در این قسمت اکسپشن هایی را لیست میکنیم که با وجود فراخوانی درست فانکشن (طبق داک‌استرینگ) ممکن است رخ دهد.

مثال زیر یک نمونه کامل از داک‌استرینگ فانکشن است:

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
    """Fetches rows from a Bigtable.

    Retrieves rows pertaining to the given keys from the Table instance
    represented by big_table.  Silly things may happen if
    other_silly_variable is not None.

    Args:
        big_table: An open Bigtable Table instance.
        keys: A sequence of strings representing the key of each table row
            to fetch.
        other_silly_variable: Another optional variable, that has a much
            longer name than the other args, and which does nothing.

    Returns:
        A dict mapping keys to the corresponding table row data
        fetched. Each row is represented as a tuple of strings. For
        example:

        {'Serak': ('Rigel VII', 'Preparer'),
         'Zim': ('Irk', 'Invader'),
         'Lrrr': ('Omicron Persei 8', 'Emperor')}

        If a key from the keys argument is missing from the dictionary,
        then that row was not found in the table.

    Raises:
        IOError: An error occurred accessing the bigtable.Table object.
    """

Class

هر کلاس هم در ابتدایی ترین خط شامل داک‌استرینگ خواهد بود. داک‌استرینگ کلاس هم علاوه بر عنوان اصلی و توضیحات شامل بخش دیگری به نام Attributes است که این بخش شامل توضیحات لازم در مورد attribute های کلاس است که دقیقا دارای فرمتی مانند بخش Args را فانکشن ها است.

به این مثال توجه کنید:

class SampleClass(object):
    """Summary of class here.

    Longer class information....
    Longer class information....

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam=False):
        """Inits SampleClass with blah."""
        self.likes_spam = likes_spam
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

نکته آخر، کامنت

همونطور که در قسمت قبل هم گفتیم گذاشتن کامنت در کد توصیه نمی‌شه. اما اینجا لازم میدونم که اشاره ای بکنم به پیشنهاد گوگل برای کامنت گذاشتن.

اگر لازم است چیزی را در code review توضیح بدید، اون رو کامنت بذارید.

http://google.github.io/styleguide/pyguide.html#385-block-and-inline-comments

گوگل پیشنهاد میده که در ۲ جا کامنت بذارید:

  • قبل از انجام عملیاتی پیچیده چند خط توضیح بدهید
# We use a weighted dictionary search to find out where i is in
# the array.  We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.
  • در انتهای یک خط کد که ممکن است خیلی واضح نباشد ( دقت کنید که در انتهای خط، ۲ فاصله، سپس علامت # و پس از آن ۱ فاصله و در انتها توضیحات قرار می‌گیرد)
if i & (i-1) == 0:  # True if i is 0 or a power of 2.