2012-04-25 37 views
26

Vì vậy, tôi đang cố gắng để tạo ra một "năng động" docstring mà là một cái gì đó như thế này:Làm thế nào để đưa một biến vào Python docstring

ANIMAL_TYPES = ["mammals", "reptiles", "other"] 

def func(animalType): 
""" This is a sample function. 

    @param animalType: "It takes one of these animal types %s" % ANIMAL_TYPES 
""" 

về cơ bản cho phép các docstring cho @param animalType chương trình bất cứ điều gì ANIMAL_TYPES có; để khi biến này được cập nhật, docstring sẽ được cập nhật tự động.

Thật không may, tuy nhiên, nó có vẻ không hoạt động ... Có ai biết nếu có cách nào để đạt được điều này?

Trả lời

12

Chuỗi được trích dẫn ba chuỗi là một chuỗi lớn. Không có gì được đánh giá bên trong chúng. Phần % là tất cả các phần của chuỗi. Bạn sẽ cần phải có nó hoạt động trên chuỗi thực tế.

def func(animalType): 
    """ 
    This is a sample function. 

    @param animalType: "It takes one of these animal types %(ANIMAL_TYPES)s" 
    """ % {'ANIMAL_TYPES': ANIMAL_TYPES} 

Tôi không chắc chắn điều này sẽ hoạt động bình thường; docstrings là một chút phép thuật. Điều này sẽ không hoạt động; docstring được đánh giá tại thời gian biên dịch (như là câu lệnh đầu tiên trong hàm, vì nó là một chuỗi ký tự — khi nó có số % trong đó nó không chỉ là một chuỗi ký tự), định dạng chuỗi diễn ra trong thời gian chạy, vì vậy __doc__ sẽ trống :

>>> def a(): 'docstring works' 
... 
>>> a.__doc__ 
'docstring works' 
>>> def b(): "formatted docstring doesn't work %s" % ':-(' 
... 
>>> b.__doc__ 
>>> 

Nếu bạn muốn làm việc theo cách này, bạn cần phải làm func.__doc__ %= {'ANIMAL_TYPES': ANIMAL_TYPES} sau khi hàm được xác định. Xin lưu ý rằng điều này sau đó sẽ vi phạm trên python -OO nếu bạn không kiểm tra xem __doc__ đã được xác định hay chưa, như -OO dải tài liệu.

>>> def c(): "formatted docstring works %s" 
... 
>>> c.__doc__ 
"formatted docstring works %s" 
>>> c.__doc__ %= 'after' 
>>> c.__doc__ 
"formatted docstring works after" 

Đây không phải là kỹ thuật chuẩn; kỹ thuật tiêu chuẩn là tham chiếu hằng số thích hợp: "Lấy một trong các loại động vật trong ANIMAL_TYPES", hoặc tương tự.

+0

Cảm ơn, Chris. Tôi có thể hỏi tại sao '__doc__' sẽ trống không trong mã bạn bỏ qua? Cảm ơn! –

+0

@JackZ: được bao trả nhiều hơn ngay bây giờ. –

+4

Lý do nó trống là vì biểu thức ** ''foo% s'% 'bar'' không phải là một chuỗi chữ, đó là một biểu thức sẽ đánh giá một chuỗi. Trình biên dịch mong đợi một chuỗi ký tự thực, như là điều đầu tiên bên trong khối, để đủ điều kiện như một docstring. –

5

Bạn cũng có thể định nghĩa một docstring sử dụng .__doc__

Ví dụ:

>>> def f(): 
     pass 
>>> x = 1 
>>> y = "docstring" 

>>> f.__doc__ = "%s string %s" % (x, y) 
>>> print(f.__doc__) 
1 string docstring 
28

Một cách để làm điều này là sử dụng một trang trí. Tôi không chắc tôi cảm thấy thế nào về điều này; Tôi thực sự đã tìm kiếm bình luận về phương pháp này và tìm thấy this answer, ghi chú đúng rằng nó có thể che giấu một vấn đề thiết kế. Tuy nhiên, trường hợp sử dụng của bạn dường như có vẻ là một cái nhìn đầu tiên về âm thanh.

Trong mọi trường hợp, đây là một cách khá thanh lịch để đạt được kết quả mà bạn đang tìm kiếm:

>>> def docstring_parameter(*sub): 
...  def dec(obj): 
...   obj.__doc__ = obj.__doc__.format(*sub) 
...   return obj 
...  return dec 
... 
>>> @docstring_parameter('Ocean') 
... def foo(): 
...  '''My Docstring Lies Over The {0}''' 
...  pass 
... 
>>> @docstring_parameter('Sea') 
... def bar(): 
...  '''My Docstring Lies Over The {0}''' 
...  pass 
... 
>>> @docstring_parameter('Docstring', 'Me') 
... def baz(): 
...  '''Oh Bring Back My {0} To {1}''' 
...  pass 
... 
>>> foo.__doc__ 
'My Docstring Lies Over The Ocean' 
>>> bar.__doc__ 
'My Docstring Lies Over The Sea' 
>>> foo.__doc__ 
'My Docstring Lies Over The Ocean' 
>>> baz.__doc__ 
'Oh Bring Back My Docstring To Me' 
1

Bạn chỉ có thể sử dụng [tham khảo chéo] [1] trong doc dây của bạn để tham khảo biến.

Vì vậy:

:param animalType: It takes one of these :data:`animal types<ANIMAL_TYPES>` 

Và trong lần thứ hai:

:param choice: can be one of :attr:`MY_CONST` 
+0

Ai đó có thể cung cấp một SSCE làm rõ làm thế nào để viết này vào một python script? Xem thêm: http://sphinx-doc.org/domains.html#cross-referencing-python-objects và http://sphinx-doc.org/domains.html#python-roles – taz

Các vấn đề liên quan