Làm thế nào để biết kiểu trả về của hàm và các kiểu đối số?


84

Trong khi tôi biết về khái niệm gõ vịt của Python, đôi khi tôi gặp khó khăn với loại đối số của các hàm hoặc loại giá trị trả về của hàm.

Bây giờ, nếu tôi tự viết hàm, tôi biết các kiểu. Nhưng điều gì sẽ xảy ra nếu ai đó muốn sử dụng và gọi các hàm của tôi, làm thế nào mà anh ấy / cô ấy dự kiến ​​biết các loại? Tôi thường đặt thông tin kiểu trong chuỗi docstring của hàm (như: "...the id argument should be an integer...""... the function will return a (string, [integer]) tuple.")

Nhưng việc tra cứu thông tin trong docstring (và đặt nó ở đó, với tư cách là một người viết mã) có thực sự là cách mà nó được cho là được thực hiện?

Chỉnh sửa: Trong khi phần lớn các câu trả lời dường như hướng đến "vâng, tài liệu!" Tôi cảm thấy điều này không phải lúc nào cũng dễ dàng đối với những loại 'phức tạp'.
Ví dụ: làm thế nào để mô tả ngắn gọn trong docstring rằng một hàm trả về danh sách các bộ giá trị, với mỗi bộ giá trị có dạng (node_id, node_name, uptime_minutes) và các phần tử tương ứng là một chuỗi, chuỗi và số nguyên?
Tài liệu docstring PEP không đưa ra bất kỳ hướng dẫn nào về điều đó.
Tôi đoán đối số sẽ là trong trường hợp đó các lớp nên được sử dụng, nhưng tôi thấy python rất linh hoạt vì nó cho phép truyền những thứ này bằng cách sử dụng danh sách và bộ giá trị, tức là không có lớp.


2
Câu trả lời ngắn gọn là có". Câu trả lời dài là "có, tất nhiên". Tôi không biết bạn đã xem nhiều mã Python chưa, nhưng có lẽ bạn nên cập nhật câu hỏi để cho biết gói nào bạn thực sự sử dụng để chúng tôi có thể hướng dẫn bạn đến mã bạn có thể đọc để xem mọi thứ được thực hiện như thế nào trong mã thư viện của bạn. đang thực sự sử dụng ngay bây giờ.
S.Lott

@ S.Lott: Tôi hiện đang vật lộn với gói cơ giới hóa, nhưng tôi đoán nó chỉ là (không may) được ghi chép kém.
Rabarberski

4
Python thú vị vì bạn có thể viết rất nhiều mã một cách nhanh chóng và bạn không phải lo lắng về những thứ vụn vặt như kiểu trả về, kiểu đối số, hiệu suất thời gian chạy, những người phải sử dụng và duy trì mã spaghetti của bạn trong 10 năm tới, v.v. Thở dài .
jarmod

Câu trả lời:


120

Mọi thứ đã thay đổi một chút kể từ năm 2011! Bây giờ có các gợi ý kiểu trong Python 3.5 mà bạn có thể sử dụng để chú thích các đối số và trả về kiểu hàm của bạn. Ví dụ điều này:

def greeting(name):
  return 'Hello, {}'.format(name)

bây giờ có thể được viết như sau:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

Như bây giờ bạn có thể thấy các loại, có một số loại kiểm tra loại tĩnh tùy chọn sẽ giúp bạn và người kiểm tra loại của bạn điều tra mã của bạn.

để biết thêm giải thích, tôi khuyên bạn nên xem bài đăng trên blog về gợi ý loại trong blog PyCharm .


Lưu ý rằng cú pháp gợi ý kiểu cũng được đề xuất cho Python 2.7 ở đây trong cùng một PEP-0484. Và nó hoạt động trong PyCharm, ít nhất là từ phiên bản 2017.3.
viddik13

1
Nếu hàm chào với định nghĩa giống hệt nhau trả về một đối tượng kiểu int, sẽ không có lỗi nào xảy ra. Vì vậy, cách sử dụng của loại kiểm tra kiểu này là gì nếu bạn đề cập đến kiểu trả về một cách rõ ràng, nhưng không tuân theo quy tắc và trả về kiểu đối tượng khác nhau?
Arashsyh

2
@Arashsyh: Vâng, bạn nói đúng, gợi ý nhập không biến Python thành ngôn ngữ nhập tĩnh, tùy thuộc vào bạn để sử dụng đúng loại theo đúng cách. Và những gợi ý kiểu đó sẽ giúp bạn - phát triển nhanh hơn, tự ghi lại mã của bạn hoặc nhận cảnh báo khi bạn làm sai một thứ gì đó. Đặc biệt khi bạn sử dụng PyCharm (hoặc IDE tương tự), nó sẽ cảnh báo bạn trong trường hợp bạn sử dụng loại khác và giúp được một số việc khác. Tôi khuyên bạn nên đọc bài đăng trên blog được đề xuất trong câu trả lời ở trên.
Nerxis

Điều này có nhanh hơn về mặt tính toán không?
Bryce Wayne

17

Đây là cách hoạt động của các ngôn ngữ động. Tuy nhiên, không phải lúc nào cũng là điều tốt, đặc biệt là nếu tài liệu kém - có ai đã cố gắng sử dụng một framework python được tài liệu kém không? Đôi khi bạn phải quay lại đọc nguồn.

Dưới đây là một số chiến lược để tránh sự cố khi gõ vịt:

  • tạo ngôn ngữ cho miền vấn đề của bạn
  • điều này sẽ giúp bạn đặt tên đúng
  • sử dụng các loại để thể hiện các khái niệm trong ngôn ngữ miền của bạn
  • tham số chức năng tên bằng cách sử dụng từ vựng ngôn ngữ miền

Ngoài ra, một trong những điểm quan trọng nhất:

  • giữ dữ liệu cục bộ nhất có thể!

Chỉ nên có một số loại được xác định rõ ràng và được ghi chép lại. Bất kỳ điều gì khác nên rõ ràng bằng cách xem mã: Đừng có các loại tham số kỳ lạ đến từ xa mà bạn không thể tìm ra bằng cách xem xét vùng lân cận của mã ...

Có liên quan, (và cả liên quan đến docstrings), có một kỹ thuật trong python được gọi là doctests. Sử dụng tài liệu đó để ghi lại cách các phương pháp của bạn dự kiến ​​sẽ được sử dụng - và đồng thời có phạm vi kiểm tra đơn vị tốt!


1
Tài liệu Numpy là một ví dụ tiêu biểu tốt cho triết lý được nêu trong câu trả lời ở trên.
Jerry

5

Có, bạn nên sử dụng docstrings để làm cho các lớp và hàm của bạn thân thiện hơn với các lập trình viên khác:

Thêm: http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

Một số trình chỉnh sửa cho phép bạn xem docstrings trong khi nhập, vì vậy nó thực sự giúp công việc dễ dàng hơn.


+1: ghi lại nó, đó là cách duy nhất lành mạnh và đó cũng là trường hợp của các ngôn ngữ được nhập tĩnh. Loại trả lại là một phần không đáng kể của toàn bộ bức tranh.
detly

Tôi thích các loại của tôi cảm ơn bạn rất nhiều. Tài liệu + các loại = Heaven
masm64

5

Tôi đã tham dự một khóa học về khóa học, trong đó có bài học, chúng tôi được dạy về công thức thiết kế.

Dưới định dạng docstring tôi thấy preety hữu ích.

vùng xác định (cơ sở, chiều cao):
    '' '(number, number) -> number # ** TypeContract **
    Trả về diện tích của một đường gấp khúc với cơ sở kích thước # ** Mô tả **
    và chiều cao

    >>> area (10,5) # ** Ví dụ **
    25.0
    >> khu vực (2,5,3)
    3,75
    ''
    return (cơ sở * chiều cao) / 2 

Tôi nghĩ nếu docstrings được viết theo cách này, nó có thể giúp ích rất nhiều cho các nhà phát triển.

Liên kết tới video [Hãy xem video] : https://www.youtube.com/watch?v=QAPg6Vb_LgI


2

Vâng, đúng vậy.

Trong Python, một hàm không phải lúc nào cũng phải trả về một biến cùng kiểu (mặc dù mã của bạn sẽ dễ đọc hơn nếu các hàm của bạn luôn trả về cùng một kiểu). Điều đó có nghĩa là bạn không thể chỉ định một kiểu trả về duy nhất cho hàm.

Theo cách tương tự, các tham số không phải lúc nào cũng phải cùng loại.


1

Ví dụ: làm thế nào để mô tả ngắn gọn trong docstring rằng một hàm trả về danh sách các bộ giá trị, với mỗi bộ giá trị có dạng (node_id, node_name, uptime_minutes) và các phần tử tương ứng là một chuỗi, chuỗi và số nguyên?

Ừm ... Không có mô tả "ngắn gọn" nào về điều này. Nó phức tạp. Bạn đã thiết kế nó phức tạp. Và nó yêu cầu tài liệu phức tạp trong docstring.

Xin lỗi, nhưng phức tạp là - tốt - phức tạp.


2
ĐỒNG Ý. Lạc đề (đại loại): nhưng thế nào sẽ là một thiết kế gọn gàng hơn? Các lớp học?
Rabarberski

@Rabarberski: Không nhất thiết. Âm thanh phức tạp là không thể tránh khỏi ở đây. Sự ngắn gọn không phải lúc nào cũng có thể đạt được hoặc thậm chí là mong muốn.
S.Lott

Một cách rõ ràng để ghi lại loại điều này là bằng cách sử dụng một cái gì đó tương tự như Java generics, như trong: list <tuple <int, str, int >>. Nhưng đó không phải là cách Python, tốt hơn hay tệ hơn.
skyler


0

Docstrings (và tài liệu nói chung). Python 3 giới thiệu các chú thích hàm (tùy chọn), như được mô tả trong PEP 3107 (nhưng đừng bỏ qua docstrings)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.