Làm cách nào để viết một hàm trong Python?

Xuyên suốt các hướng dẫn trước trong loạt bài này, bạn đã thấy nhiều ví dụ minh họa việc sử dụng. In this tutorial, you’ll learn how to define your own Python function. You’ll learn when to divide your program into separate user-defined functions and what tools you’ll need to do this

Here’s what you’ll learn in this tutorial

  • How functions work in Python and why they’re beneficial
  • How to define and call your own Python function
  • Mechanisms for passing arguments to your function
  • How to return data from your function back to the calling environment

Free PDF Download. Python 3 Cheat Sheet

Functions in Python

You may be familiar with the mathematical concept of a function. A function is a relationship or mapping between one or more inputs and a set of outputs. In mathematics, a function is typically represented like this

Làm cách nào để viết một hàm trong Python?

Here,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
16 is a function that operates on the inputs
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 and
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
18. The output of the function is
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
19. However, programming functions are much more generalized and versatile than this mathematical definition. In fact, appropriate function definition and use is so critical to proper software development that virtually all modern programming languages support both built-in and user-defined functions

In programming, a function is a self-contained block of code that encapsulates a specific task or related group of tasks. In previous tutorials in this series, you’ve been introduced to some of the built-in functions provided by Python. , for example, takes one argument and returns that object’s unique integer identifier

>>>

>>> s = 'foobar'
>>> id(s)
56313440

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
21 returns the length of the argument passed to it

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
22 takes an iterable as its argument and returns
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
23 if any of the items in the iterable are and
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
24 otherwise

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True

Each of these built-in functions performs a specific task. The code that accomplishes the task is defined somewhere, but you don’t need to know where or even how the code works. All you need to know about is the function’s interface

  1. What arguments (if any) it takes
  2. What values (if any) it returns

Then you call the function and pass the appropriate arguments. Program execution goes off to the designated body of code and does its useful thing. When the function is finished, execution returns to your code where it left off. The function may or may not return data for your code to use, as the examples above do

When you define your own Python function, it works just the same. From somewhere in your code, you’ll call your Python function and program execution will transfer to the body of code that makes up the function

Note. In this case, you will know where the code is and exactly how it works because you wrote it

When the function is finished, execution returns to the location where the function was called. Depending on how you designed the function’s interface, data may be passed in when the function is called, and return values may be passed back when it finishes

Remove ads

The Importance of Python Functions

Virtually all programming languages used today support a form of user-defined functions, although they aren’t always called functions. In other languages, you may see them referred to as one of the following

  • Subroutines
  • Procedures
  • Methods
  • Subprograms

So, why bother defining functions? There are several very good reasons. Let’s go over a few now

Abstraction and Reusability

Giả sử bạn viết một số mã làm điều gì đó hữu ích. As you continue development, you find that the task performed by that code is one you need often, in many different locations within your application. What should you do? Well, you could just replicate the code over and over again, using your editor’s copy-and-paste capability

Later on, you’ll probably decide that the code in question needs to be modified. You’ll either find something wrong with it that needs to be fixed, or you’ll want to enhance it in some way. If copies of the code are scattered all over your application, then you’ll need to make the necessary changes in every location

Note. At first blush, that may seem like a reasonable solution, but in the long term, it’s likely to be a maintenance nightmare. While your code editor may help by providing a search-and-replace function, this method is error-prone, and you could easily introduce bugs into your code that will be difficult to find

A better solution is to define a Python function that performs the task. Anywhere in your application that you need to accomplish the task, you simply call the function. Down the line, if you decide to change how it works, then you only need to change the code in one location, which is the place where the function is defined. The changes will automatically be picked up anywhere the function is called

The abstraction of functionality into a function definition is an example of the Don’t Repeat Yourself (DRY) Principle of software development. Đây được cho là động lực mạnh nhất để sử dụng các chức năng

tính mô đun

Các chức năng cho phép chia các quy trình phức tạp thành các bước nhỏ hơn. Ví dụ, hãy tưởng tượng rằng bạn có một chương trình đọc tệp, xử lý nội dung tệp và sau đó ghi tệp đầu ra. Mã của bạn có thể trông như thế này

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>

Trong ví dụ này, chương trình chính là một loạt mã được xâu thành một chuỗi dài, với khoảng trắng và nhận xét để giúp tổ chức chương trình. Tuy nhiên, nếu mã trở nên dài hơn và phức tạp hơn nhiều, thì bạn sẽ ngày càng gặp khó khăn trong việc xoay sở với nó.

Ngoài ra, bạn có thể cấu trúc mã giống như sau

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()

Ví dụ này được mô đun hóa. Thay vì tất cả mã được xâu chuỗi lại với nhau, nó được chia thành các chức năng riêng biệt, mỗi chức năng tập trung vào một nhiệm vụ cụ thể. Những tác vụ đó được đọc, xử lý và ghi. Chương trình chính bây giờ chỉ cần gọi lần lượt từng cái này

Ghi chú. Từ khóa

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
25 giới thiệu một định nghĩa hàm Python mới. Bạn sẽ tìm hiểu tất cả về điều này rất sớm

Trong cuộc sống, bạn luôn làm những việc như thế này, ngay cả khi bạn không nghĩ rõ ràng về nó theo cách đó. Nếu bạn muốn di chuyển một số kệ chứa đầy đồ đạc từ bên này sang bên kia ga-ra của mình, thì hy vọng rằng bạn sẽ không chỉ đứng đó và nghĩ vu vơ, “Ôi trời. Tôi cần phải di chuyển tất cả những thứ đó ở đó. Làm thế nào để làm điều đó???"

  1. Lấy tất cả những thứ ra khỏi kệ
  2. Tháo rời các kệ
  3. Mang các bộ phận của kệ qua nhà để xe đến vị trí mới
  4. Lắp ráp lại các kệ
  5. Mang đồ qua nhà để xe
  6. Đặt lại những thứ trên kệ

Chia một nhiệm vụ lớn thành các nhiệm vụ nhỏ hơn, nhỏ hơn giúp làm cho nhiệm vụ lớn dễ suy nghĩ và quản lý hơn. Khi các chương trình trở nên phức tạp hơn, việc mô đun hóa chúng theo cách này ngày càng trở nên có lợi.

Remove ads

Tách không gian tên

Không gian tên là một vùng của chương trình trong đó các mã định danh có ý nghĩa. Như bạn sẽ thấy bên dưới, khi một hàm Python được gọi, một không gian tên mới được tạo cho hàm đó, một không gian tên khác với tất cả các không gian tên khác đã tồn tại

Kết quả thực tế của điều này là các biến có thể được xác định và sử dụng trong một hàm Python ngay cả khi chúng có cùng tên với các biến được xác định trong các hàm khác hoặc trong chương trình chính. Trong những trường hợp này, sẽ không có sự nhầm lẫn hoặc can thiệp vì chúng được giữ trong các không gian tên riêng biệt

Điều này có nghĩa là khi bạn viết mã trong một hàm, bạn có thể sử dụng tên biến và mã định danh mà không phải lo lắng về việc liệu chúng đã được sử dụng ở đâu khác bên ngoài hàm chưa. Điều này giúp giảm thiểu đáng kể các lỗi trong mã

Ghi chú. Bạn sẽ tìm hiểu thêm về không gian tên ở phần sau của loạt bài này

Hy vọng rằng bạn đã đủ thuyết phục về ưu điểm của các chức năng và mong muốn tạo ra một số. Hãy xem làm thế nào

Gọi hàm và định nghĩa

Cú pháp thông thường để xác định hàm Python như sau

def <function_name>([<parameters>]):
    <statement(s)>

Các thành phần của định nghĩa được giải thích trong bảng dưới đây

ComponentMeaning

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
25Từ khóa thông báo cho Python rằng một hàm đang được xác định
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
27Một mã định danh Python hợp lệ đặt tên cho hàm
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
28Một danh sách các tham số tùy chọn, được phân tách bằng dấu phẩy có thể được truyền cho hàm
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
29Dấu câu biểu thị phần cuối của tiêu đề hàm Python (danh sách tên và tham số)
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
30A

Mục cuối cùng,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
30, được gọi là phần thân của hàm. Phần thân là một khối các câu lệnh sẽ được thực hiện khi hàm được gọi. Phần thân của hàm Python được xác định bằng cách thụt đầu dòng theo quy định. Điều này giống như các khối mã được liên kết với cấu trúc điều khiển, chẳng hạn như câu lệnh
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
32 hoặc
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
33

Cú pháp gọi hàm Python như sau

<function_name>([<arguments>])

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
34 là các giá trị được truyền vào hàm. Chúng tương ứng với
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
28 trong định nghĩa hàm Python. Bạn có thể định nghĩa một hàm không nhận bất kỳ đối số nào, nhưng dấu ngoặc đơn vẫn được yêu cầu. Cả định nghĩa hàm và lời gọi hàm phải luôn bao gồm dấu ngoặc đơn, ngay cả khi chúng trống

Như thường lệ, bạn sẽ bắt đầu với một ví dụ nhỏ và thêm độ phức tạp từ đó. Hãy ghi nhớ truyền thống toán học lâu đời, bạn sẽ gọi hàm Python đầu tiên của mình là

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36. Đây là một tệp kịch bản,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
37, xác định và gọi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')

Đây là cách mã này hoạt động

  1. Dòng 1 sử dụng từ khóa

    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    25 để chỉ ra rằng một chức năng đang được xác định. Việc thực hiện câu lệnh
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    25 chỉ đơn thuần tạo ra định nghĩa của
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36. Tất cả các dòng sau được thụt vào (dòng 2 đến dòng 3) trở thành một phần của phần thân của
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 và được lưu trữ dưới dạng định nghĩa của nó, nhưng chúng chưa được thực thi

  2. Dòng 4 là một chút khoảng trắng giữa định nghĩa hàm và dòng đầu tiên của chương trình chính. Mặc dù nó không cần thiết về mặt cú pháp, nhưng thật tuyệt khi có. Để tìm hiểu thêm về khoảng trắng xung quanh các định nghĩa hàm Python cấp cao nhất, hãy xem Viết mã Pythonic đẹp với PEP 8

  3. Dòng 5 là câu lệnh đầu tiên không được thụt lề vì nó không phải là một phần của định nghĩa về

    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36. Nó bắt đầu chương trình chính. Khi chương trình chính thực thi, câu lệnh này được thực hiện đầu tiên

  4. Dòng 6 là cuộc gọi đến

    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36. Lưu ý rằng dấu ngoặc đơn trống luôn được yêu cầu trong cả định nghĩa hàm và lời gọi hàm, ngay cả khi không có tham số hoặc đối số. Quá trình thực thi tiếp tục đến
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 và các câu lệnh trong phần thân của
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 được thực thi

  5. Dòng 7 là dòng tiếp theo để thực thi sau khi phần thân của

    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 kết thúc. Việc thực thi trả về câu lệnh
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    48 này

Trình tự thực hiện (hoặc luồng điều khiển) cho

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
37 được hiển thị trong sơ đồ sau

Làm cách nào để viết một hàm trong Python?

Khi

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
37 được chạy từ dấu nhắc lệnh của Windows, kết quả như sau

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()

Đôi khi, bạn có thể muốn định nghĩa một hàm rỗng không làm gì cả. Đây được gọi là sơ khai, thường là trình giữ chỗ tạm thời cho hàm Python sẽ được triển khai đầy đủ sau này. Giống như một khối trong cấu trúc điều khiển không thể để trống, phần thân của hàm cũng vậy. Để định nghĩa một hàm sơ khai, hãy sử dụng câu lệnh

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
51

>>>

>>> def f():
..     pass
...
>>> f()

Như bạn có thể thấy ở trên, lệnh gọi hàm sơ khai hợp lệ về mặt cú pháp nhưng không thực hiện bất kỳ điều gì

Remove ads

Truyền đối số

Cho đến giờ trong hướng dẫn này, các hàm bạn đã xác định chưa nhận bất kỳ đối số nào. Điều đó đôi khi có thể hữu ích và thỉnh thoảng bạn sẽ viết các hàm như vậy. Tuy nhiên, thường xuyên hơn, bạn sẽ muốn truyền dữ liệu vào một hàm để hành vi của nó có thể thay đổi từ lần gọi này sang lần gọi tiếp theo. Hãy xem làm thế nào để làm điều đó

Đối số vị trí

Cách đơn giản nhất để truyền đối số cho hàm Python là sử dụng đối số vị trí (còn gọi là đối số bắt buộc). Trong định nghĩa hàm, bạn chỉ định danh sách tham số được phân tách bằng dấu phẩy bên trong dấu ngoặc đơn

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
0

Khi hàm được gọi, bạn chỉ định một danh sách các đối số tương ứng

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
1

Các tham số (

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
52,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
53 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
54) hoạt động giống như các biến được xác định cục bộ cho hàm. Khi hàm được gọi, các đối số được truyền (
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
55,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
56 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
57) được liên kết với các tham số theo thứ tự, như thể bằng cách gán biến

ParameterArgument

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
52←
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
55
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
53←
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
61
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
54←
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
57

Trong một số văn bản lập trình, các tham số được đưa ra trong định nghĩa hàm được gọi là tham số hình thức và các đối số trong lệnh gọi hàm được gọi là tham số thực

Làm cách nào để viết một hàm trong Python?

Mặc dù các đối số vị trí là cách đơn giản nhất để truyền dữ liệu đến một hàm, nhưng chúng cũng kém linh hoạt nhất. Đối với người mới bắt đầu, thứ tự của các đối số trong lệnh gọi phải khớp với thứ tự của các tham số trong định nghĩa. Tất nhiên, không có gì ngăn bạn chỉ định các đối số vị trí không theo thứ tự

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
2

Hàm thậm chí có thể vẫn chạy, như trong ví dụ trên, nhưng rất khó có thể tạo ra kết quả chính xác. Người lập trình có trách nhiệm xác định chức năng để ghi lại các đối số phù hợp và trách nhiệm của người dùng chức năng là nhận thức được thông tin đó và tuân theo thông tin đó

Với các đối số vị trí, các đối số trong lệnh gọi và các tham số trong định nghĩa phải thống nhất không chỉ về thứ tự mà còn về số lượng. Đó là lý do đối số vị trí cũng được gọi là đối số bắt buộc. Bạn không thể bỏ bất kỳ phần nào khi gọi hàm

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
3

Bạn cũng không thể chỉ định những cái bổ sung

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
4

Đối số vị trí dễ sử dụng về mặt khái niệm, nhưng chúng không dễ tha thứ. Bạn phải chỉ định cùng một số đối số trong lệnh gọi hàm như có các tham số trong định nghĩa và theo đúng thứ tự. Trong các phần tiếp theo, bạn sẽ thấy một số kỹ thuật chuyển đối số giúp nới lỏng các hạn chế này

Đối số từ khóa

Khi gọi một hàm, bạn có thể chỉ định các đối số ở dạng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
64. Trong trường hợp đó, mỗi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
65 phải khớp với một tham số trong định nghĩa hàm Python. Ví dụ: chức năng được xác định trước đó _________36 có thể được gọi với các đối số từ khóa như sau

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
5

Tham chiếu một từ khóa không khớp với bất kỳ tham số nào đã khai báo sẽ tạo ra một ngoại lệ

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
6

Sử dụng các đối số từ khóa sẽ loại bỏ hạn chế về thứ tự đối số. Mỗi đối số từ khóa chỉ định rõ ràng một tham số cụ thể theo tên, vì vậy bạn có thể chỉ định chúng theo bất kỳ thứ tự nào và Python sẽ vẫn biết đối số nào đi với tham số nào

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
7

Tuy nhiên, giống như đối số vị trí, số lượng đối số và tham số vẫn phải khớp với nhau

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
8

Vì vậy, các đối số từ khóa cho phép linh hoạt trong thứ tự các đối số chức năng được chỉ định, nhưng số lượng đối số vẫn còn cứng nhắc

Bạn có thể gọi một hàm bằng cách sử dụng cả đối số vị trí và từ khóa

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
9

Khi cả hai đối số vị trí và từ khóa đều xuất hiện, tất cả các đối số vị trí phải xuất hiện trước

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
0

Khi bạn đã chỉ định một đối số từ khóa, không thể có bất kỳ đối số vị trí nào ở bên phải của nó

Để tìm hiểu thêm về các tham số vị trí và từ khóa, hãy xem khóa học Real Python Khám phá các tham số chức năng đặc biệt

Remove ads

Thông số mặc định

Nếu một tham số được chỉ định trong định nghĩa hàm Python có dạng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
67, thì
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
68 sẽ trở thành giá trị mặc định cho tham số đó. Các tham số được xác định theo cách này được gọi là tham số mặc định hoặc tùy chọn. Một ví dụ về định nghĩa hàm với các tham số mặc định được hiển thị bên dưới

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
1

Khi phiên bản

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 này được gọi, bất kỳ đối số nào bị bỏ qua sẽ nhận giá trị mặc định của nó

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
2

Tóm tắt

  • Các đối số vị trí phải thống nhất về thứ tự và số với các tham số được khai báo trong định nghĩa hàm
  • Các đối số từ khóa phải phù hợp với các tham số đã khai báo về số lượng, nhưng chúng có thể được chỉ định theo thứ tự tùy ý
  • Tham số mặc định cho phép bỏ qua một số đối số khi gọi hàm

Giá trị tham số mặc định có thể thay đổi

Mọi thứ có thể trở nên kỳ lạ nếu bạn chỉ định một giá trị tham số mặc định là một đối tượng có thể thay đổi. Xem xét định nghĩa hàm Python này

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
3

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 lấy một tham số danh sách, nối chuỗi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
71 vào cuối danh sách và trả về kết quả

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
4

Giá trị mặc định cho tham số

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 là danh sách trống, vì vậy nếu
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi mà không có bất kỳ đối số nào, thì giá trị trả về là danh sách có phần tử duy nhất
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
71

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
5

Mọi thứ đều có ý nghĩa cho đến nay. Bây giờ, bạn mong đợi điều gì sẽ xảy ra nếu

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi mà không có bất kỳ tham số nào lần thứ hai và thứ ba?

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
6

Ối. Bạn có thể mong đợi mỗi cuộc gọi tiếp theo cũng trả về danh sách đơn lẻ

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
76, giống như cuộc gọi đầu tiên. Thay vào đó, giá trị trả lại tiếp tục tăng. Chuyện gì đã xảy ra thế?

Trong Python, các giá trị tham số mặc định chỉ được xác định một lần khi hàm được xác định (tức là khi câu lệnh

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
25 được thực thi). Giá trị mặc định không được xác định lại mỗi khi hàm được gọi. Vì vậy, mỗi lần bạn gọi ___0_______36 mà không có tham số, bạn đang thực hiện ___0_______79 trên cùng một danh sách

Bạn có thể chứng minh điều này với

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
20

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
7

Mã định danh đối tượng được hiển thị xác nhận rằng, khi

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 được phép đặt mặc định, giá trị là cùng một đối tượng với mỗi cuộc gọi. Vì các danh sách có thể thay đổi, nên mỗi lệnh gọi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
79 tiếp theo sẽ khiến danh sách dài hơn. Đây là một cạm bẫy phổ biến và được ghi lại khá rõ ràng khi bạn đang sử dụng một đối tượng có thể thay đổi làm giá trị mặc định của tham số. Nó có khả năng dẫn đến hành vi mã khó hiểu và có lẽ tốt nhất nên tránh

Như một giải pháp thay thế, hãy cân nhắc sử dụng một giá trị đối số mặc định báo hiệu rằng không có đối số nào được chỉ định. Hầu hết mọi giá trị sẽ hoạt động, nhưng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
83 là lựa chọn phổ biến. Khi giá trị sentinel cho biết không có đối số nào được đưa ra, hãy tạo một danh sách trống mới bên trong hàm

>>>

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
8

Lưu ý cách điều này đảm bảo rằng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 hiện thực sự mặc định là danh sách trống bất cứ khi nào
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi mà không có đối số

Remove ads

Pass-By-Value vs Pass-By-Reference trong Pascal

Trong thiết kế ngôn ngữ lập trình, có hai mô hình phổ biến để truyền đối số cho hàm

  1. Pass-by-giá trị. Một bản sao của đối số được chuyển đến hàm
  2. Chuyển qua tham chiếu. Một tham chiếu đến đối số được chuyển đến hàm

Các cơ chế khác tồn tại, nhưng về cơ bản chúng là các biến thể của hai cơ chế này. Trong phần này, bạn sẽ đi một đoạn ngắn từ Python và xem xét ngắn gọn về Pascal, một ngôn ngữ lập trình tạo ra sự khác biệt đặc biệt rõ ràng giữa hai ngôn ngữ này.

Ghi chú. Đừng lo lắng nếu bạn không quen thuộc với Pascal. Các khái niệm này tương tự như các khái niệm của Python và các ví dụ được hiển thị kèm theo lời giải thích đủ chi tiết để bạn có được ý tưởng chung. Khi bạn đã thấy cách truyền đối số hoạt động trong Pascal, chúng ta sẽ quay lại Python và bạn sẽ thấy nó so sánh như thế nào

Đây là những gì bạn cần biết về cú pháp Pascal

  • thủ tục. Một thủ tục trong Pascal tương tự như một hàm trong Python
  • Dấu hai chấm bằng. Toán tử này (
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    86) dùng để gán trong Pascal. Nó tương tự như dấu bằng (_______0_______87) trong Python
  • >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    88. Chức năng này hiển thị dữ liệu cho bảng điều khiển, tương tự như của Python
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    48

Với một chút nền tảng đó, đây là ví dụ Pascal đầu tiên

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
9

Đây là những gì đang xảy ra

  • Dòng 12. Chương trình chính định nghĩa một biến số nguyên
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17
  • dòng 15. It initially assigns
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 the value
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92
  • Dòng 17. Sau đó nó gọi thủ tục _______0_______36, chuyển _________17 làm đối số
  • Line 5. Bên trong
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36, câu lệnh
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    88 cho biết tham số tương ứng
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    97 ban đầu là
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92, giá trị được truyền vào
  • Line 6.
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    97 is then assigned the value
    >>> any([False, False, False])
    False
    >>> any([False, True, False])
    True
    
    >>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
    False
    >>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
    True
    
    00
  • Line 7. This value is verified by this
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    88 statement executed just before
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 exits
  • Line 18. Back in the calling environment of the main program, this
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    88 statement shows that after
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    36 returns,
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 is still
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92, as it was prior to the procedure call

Running this code generates the following output

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
0

In this example,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 is passed by value, so
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 receives only a copy. When the corresponding parameter
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 is modified,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 is unaffected

Note. If you want to see this in action, then you can run the code for yourself using an online Pascal compiler

Just follow these steps

  1. Copy the code from the code box above
  2. Visit the Online Pascal Compiler
  3. In the code box on the left, replace any existing contents with the code you copied in step 1
  4. Click Execute

You should see the same output as above

Now, compare this with the next example

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
1

This code is identical to the first example, with one change. It’s the presence of the word

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
11 in front of
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 in the definition of procedure
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 on line 3. That indicates that the argument to
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 is passed by reference. Changes made to the corresponding parameter
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 will also modify the argument in the calling environment

The output from this code is the same as before, except for the last line

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
2

Again,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 is assigned the value
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
00 inside
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 as before. Nhưng lần này, khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trở lại, thì
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 trong chương trình chính cũng đã được sửa đổi

Trong nhiều ngôn ngữ lập trình, về cơ bản đó là sự khác biệt giữa pass-by-value và pass-by-reference

  • Nếu một biến được truyền theo giá trị, thì hàm có một bản sao để hoạt động, nhưng nó không thể sửa đổi giá trị ban đầu trong môi trường gọi
  • Nếu một biến được truyền theo tham chiếu, thì bất kỳ thay đổi nào mà hàm thực hiện đối với tham số tương ứng sẽ ảnh hưởng đến giá trị trong môi trường gọi

Lý do tại sao xuất phát từ ý nghĩa của một tài liệu tham khảo trong các ngôn ngữ này. Các giá trị biến được lưu trữ trong bộ nhớ. Trong Pascal và các ngôn ngữ tương tự, tham chiếu về cơ bản là địa chỉ của vị trí bộ nhớ đó, như minh họa bên dưới

Làm cách nào để viết một hàm trong Python?

Trong sơ đồ bên trái,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 có bộ nhớ được phân bổ trong không gian tên của chương trình chính. Khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi, giá trị
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 được truyền vào, do đó, bộ nhớ cho tham số tương ứng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 được phân bổ trong không gian tên của
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 và giá trị của
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 được sao chép vào đó. Khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 sửa đổi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97, bản sao cục bộ này được thay đổi. Giá trị của
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 trong môi trường gọi vẫn không bị ảnh hưởng

Trong sơ đồ bên phải,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 được chuyển qua tham chiếu. Tham số tương ứng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 trỏ đến địa chỉ thực trong không gian tên của chương trình chính nơi lưu trữ giá trị của
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17. Khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 sửa đổi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97, nó sẽ sửa đổi giá trị ở vị trí đó, giống như khi chương trình chính đang sửa đổi chính
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17

Remove ads

Pass-By-Value vs Pass-By-Reference trong Python

Các tham số trong Python có truyền theo giá trị hoặc theo tham chiếu không? . Đó là bởi vì một tham chiếu không có nghĩa hoàn toàn giống như trong Python như trong Pascal

Nhớ lại rằng trong Python, mọi phần dữ liệu đều là một đối tượng. Một tham chiếu trỏ đến một đối tượng, không phải là một vị trí bộ nhớ cụ thể. Điều đó có nghĩa là phép gán không được hiểu theo cùng một cách trong Python như trong Pascal. Xét cặp câu lệnh sau trong Pascal

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
3

Chúng được giải thích theo cách này

  • Biến
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 tham chiếu đến một vị trí bộ nhớ cụ thể
  • Câu lệnh đầu tiên đặt giá trị
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92 vào vị trí đó
  • Câu lệnh tiếp theo ghi đè lên
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92 và thay vào đó đặt
    >>> any([False, False, False])
    False
    >>> any([False, True, False])
    True
    
    >>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
    False
    >>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
    True
    
    00

Ngược lại, trong Python, các câu lệnh gán tương tự như sau

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
4

Các câu lệnh gán này có ý nghĩa như sau

  • Câu lệnh đầu tiên làm cho
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 trỏ đến một đối tượng có giá trị là
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    92
  • Câu lệnh tiếp theo gán lại
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 như một tham chiếu mới đến một đối tượng khác có giá trị là
    >>> any([False, False, False])
    False
    >>> any([False, True, False])
    True
    
    >>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
    False
    >>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
    True
    
    00. Nói theo một cách khác, phép gán thứ hai liên kết lại
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 với một đối tượng khác có giá trị
    >>> any([False, False, False])
    False
    >>> any([False, True, False])
    True
    
    >>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
    False
    >>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
    True
    
    00

Trong Python, khi bạn truyền một đối số cho một hàm, một rebinding tương tự sẽ xảy ra. Hãy xem xét ví dụ này

>>>

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
5

Trong chương trình chính, câu lệnh

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
46 trên dòng 4 tạo một tham chiếu có tên
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 được liên kết với một đối tượng có giá trị là
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
92. Sau đó,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi ở dòng 5, với đối số là
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17. Khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 bắt đầu lần đầu tiên, một tham chiếu mới có tên là
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 được tạo, tham chiếu này ban đầu trỏ đến cùng một đối tượng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
92 như
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17

Làm cách nào để viết một hàm trong Python?

Tuy nhiên, khi câu lệnh

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
55 trên dòng 2 được thực thi,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 liên kết lại
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 với một đối tượng mới có giá trị là
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
00. Hai tài liệu tham khảo,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97, không được tách rời khỏi nhau. Không có gì khác mà
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 làm sẽ ảnh hưởng đến
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 và khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 kết thúc,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 sẽ vẫn trỏ đến đối tượng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
92, giống như trước khi gọi hàm

Làm cách nào để viết một hàm trong Python?

Bạn có thể xác nhận tất cả điều này bằng cách sử dụng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
20. Đây là phiên bản tăng cường một chút của ví dụ trên hiển thị số nhận dạng số của các đối tượng liên quan

>>>

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
6

Khi

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 bắt đầu lần đầu tiên,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 đều trỏ đến cùng một đối tượng, có
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
20 là
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
71. Sau khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 thực hiện câu lệnh
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
55 ở dòng 3,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
97 chỉ vào một đối tượng khác có
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
20 là
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
76. Kết nối với đối tượng ban đầu trong môi trường gọi bị mất

Truyền đối số trong Python có phần kết hợp giữa truyền theo giá trị và truyền theo tham chiếu. Những gì được truyền cho hàm là một tham chiếu đến một đối tượng, nhưng tham chiếu được truyền theo giá trị

Ghi chú. Cơ chế truyền đối số của Python đã được gọi là chuyển từng lần gán. Điều này là do các tên tham số được liên kết với các đối tượng trên mục nhập hàm trong Python và phép gán cũng là quá trình liên kết tên với một đối tượng. Bạn cũng có thể thấy các thuật ngữ truyền theo đối tượng, tham chiếu theo đối tượng hoặc chia sẻ theo đối tượng

Điểm mấu chốt ở đây là một hàm Python không thể thay đổi giá trị của một đối số bằng cách gán lại tham số tương ứng cho một thứ khác. Ví dụ sau minh họa điều này

>>>

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
7

Ở đây, các đối tượng thuộc loại

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
77,
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
78,
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
79,
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
80 và
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
81 được truyền cho
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 làm đối số.
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 cố gắng gán từng cái cho đối tượng chuỗi
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
84, nhưng như bạn có thể thấy, khi quay lại môi trường gọi, tất cả chúng đều không thay đổi. Ngay sau khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 thực thi nhiệm vụ
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
86, tham chiếu sẽ phục hồi và kết nối với đối tượng ban đầu bị mất

Điều đó có nghĩa là một hàm Python không bao giờ có thể sửa đổi các đối số của nó? . Xem những gì xảy ra ở đây

>>>

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
8

Trong trường hợp này, đối số của

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 là một. Khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 được gọi, một tham chiếu đến
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 được truyền. Bạn đã thấy rằng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 không thể chỉ định lại
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 bán buôn. Nếu
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 được gán cho một thứ khác, thì nó sẽ được liên kết với một đối tượng khác và kết nối với
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 sẽ bị mất

Tuy nhiên,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 có thể sử dụng tham chiếu để thực hiện các sửa đổi bên trong
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72. Ở đây,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 đã sửa đổi phần tử đầu tiên. Bạn có thể thấy rằng một khi hàm trả về, trên thực tế,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
72 đã bị thay đổi trong môi trường gọi. Khái niệm tương tự áp dụng cho một cuốn từ điển

>>>

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
9

Ở đây,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 sử dụng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 làm tham chiếu để thực hiện thay đổi bên trong
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
00. Sự thay đổi đó được phản ánh trong môi trường cuộc gọi sau khi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trả về

Remove ads

Tóm tắt thông qua đối số

Truyền đối số trong Python có thể được tóm tắt như sau. Truyền một đối tượng bất biến, chẳng hạn như

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
77,
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
80,
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
04 hoặc , cho một hàm Python hoạt động giống như truyền theo giá trị. Chức năng không thể sửa đổi đối tượng trong môi trường gọi

Truyền một đối tượng có thể thay đổi, chẳng hạn như ,

>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
78 hoặc
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
79 hoạt động phần nào — nhưng không chính xác — giống như truyền theo tham chiếu. Hàm không thể chỉ định lại toàn bộ đối tượng nhưng có thể thay đổi các mục tại chỗ bên trong đối tượng và những thay đổi này sẽ được phản ánh trong môi trường gọi

Phản ứng phụ

Vì vậy, trong Python, bạn có thể sửa đổi một đối số từ bên trong một hàm để thay đổi được phản ánh trong môi trường gọi. Nhưng bạn có nên làm điều này?

Tổng quát hơn, một hàm Python được cho là gây ra tác dụng phụ nếu nó sửa đổi môi trường gọi của nó theo bất kỳ cách nào. Changing the value of a function argument is just one of the possibilities

Ghi chú. Có lẽ bạn đã quen thuộc với các tác dụng phụ trong lĩnh vực sức khỏe con người, trong đó thuật ngữ này thường đề cập đến hậu quả không mong muốn của thuốc. Thông thường, hậu quả là không mong muốn, chẳng hạn như nôn mửa hoặc an thần. Mặt khác, tác dụng phụ có thể được sử dụng có chủ ý. Ví dụ: một số loại thuốc gây kích thích thèm ăn, có thể được sử dụng để tạo lợi thế, ngay cả khi đó không phải là mục đích chính của thuốc

Khái niệm này tương tự trong lập trình. Nếu tác dụng phụ là một phần được ghi chép rõ ràng trong đặc tả chức năng và người dùng chức năng nhận thức rõ ràng về thời điểm và cách thức môi trường gọi có thể được sửa đổi, thì điều đó có thể ổn. Nhưng một lập trình viên có thể không phải lúc nào cũng ghi lại chính xác các tác dụng phụ hoặc thậm chí họ có thể không biết rằng các tác dụng phụ đang xảy ra

Khi chúng bị ẩn hoặc không mong đợi, các tác dụng phụ có thể dẫn đến các lỗi chương trình rất khó theo dõi. Nói chung, tốt nhất là tránh chúng

Tuyên bố # Main program # Code to read file in # Code to process file # Code to write file out 09

Hàm Python để làm gì sau đó? . Làm thế nào một chức năng nên ảnh hưởng đến người gọi của nó?

Chà, một khả năng là sử dụng các giá trị trả về của hàm. Câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 trong hàm Python phục vụ hai mục đích

  1. Nó ngay lập tức kết thúc chức năng và chuyển quyền kiểm soát thực thi trở lại người gọi
  2. Nó cung cấp một cơ chế mà chức năng có thể chuyển dữ liệu trở lại người gọi

Thoát khỏi một chức năng

Trong một hàm, câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 khiến hàm Python bị thoát ngay lập tức và chuyển việc thực thi trở lại trình gọi

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
0

Trong ví dụ này, câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 thực sự là thừa. Một hàm sẽ trở lại nơi gọi khi nó kết thúc—nghĩa là sau khi câu lệnh cuối cùng của thân hàm được thực thi. Vì vậy, chức năng này sẽ hoạt động giống hệt nhau mà không có câu lệnh
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09

Tuy nhiên, câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 không cần phải ở cuối hàm. Chúng có thể xuất hiện ở bất kỳ đâu trong thân hàm và thậm chí nhiều lần. Hãy xem xét ví dụ này

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
1

Hai lệnh gọi đầu tiên đến ____0_______36 không tạo ra bất kỳ đầu ra nào, bởi vì câu lệnh ____________09 được thực thi và hàm thoát sớm, trước khi đạt được câu lệnh ________48 trên dòng 6

Loại mô hình này có thể hữu ích để kiểm tra lỗi trong một chức năng. Bạn có thể kiểm tra một số điều kiện lỗi khi bắt đầu chức năng, với các câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 giải quyết nếu có sự cố

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
2

Nếu không gặp phải tình trạng lỗi nào, thì chức năng có thể tiến hành xử lý bình thường

Remove ads

Trả lại dữ liệu cho người gọi

Ngoài việc thoát khỏi một chức năng, câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 còn được sử dụng để truyền dữ liệu trở lại người gọi. Nếu một câu lệnh
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 bên trong hàm Python được theo sau bởi một biểu thức, thì trong môi trường gọi, lệnh gọi hàm ước tính giá trị của biểu thức đó

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
3

Ở đây, giá trị của biểu thức

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trên dòng 5 là
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
84, giá trị này sau đó được gán cho biến
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
23

Một hàm có thể trả về bất kỳ loại đối tượng nào. Trong Python, điều đó có nghĩa là bất cứ thứ gì. Trong môi trường gọi, lệnh gọi hàm có thể được sử dụng về mặt cú pháp theo bất kỳ cách nào phù hợp với loại đối tượng mà hàm trả về

Ví dụ, trong mã này,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trả về một từ điển. Khi đó, trong môi trường gọi, biểu thức
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 đại diện cho một từ điển và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
26 là một tham chiếu khóa hợp lệ trong từ điển đó

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
4

Trong ví dụ tiếp theo,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trả về một chuỗi mà bạn có thể cắt như bất kỳ chuỗi nào khác

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
5

Ở đây,

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 trả về một danh sách có thể được lập chỉ mục hoặc cắt lát

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
6

Nếu nhiều biểu thức được phân tách bằng dấu phẩy được chỉ định trong câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09, thì chúng sẽ được đóng gói và trả về dưới dạng một

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
7

Khi không có giá trị trả về nào được đưa ra, một hàm Python sẽ trả về giá trị Python đặc biệt

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
83

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
8

Điều tương tự cũng xảy ra nếu thân hàm hoàn toàn không chứa câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 và hàm bị lỗi ở cuối

>>>

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
9

Nhớ lại điều đó là sai khi được đánh giá trong ngữ cảnh Boolean

Vì các hàm thoát ra thông qua một câu lệnh

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
09 trống hoặc rơi ra khỏi kết thúc trả về
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
83, nên có thể sử dụng lệnh gọi tới một hàm như vậy trong ngữ cảnh Boolean

>>>

def <function_name>([<parameters>]):
    <statement(s)>
0

Here, calls to both

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 and
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
36 are falsy, so
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
37 is as well, and the
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
38 clause executes

Remove ads

Xem lại tác dụng phụ

Giả sử bạn muốn viết một hàm nhận một đối số nguyên và nhân đôi nó. Nghĩa là, bạn muốn truyền một biến số nguyên cho hàm và khi hàm trả về, giá trị của biến trong môi trường gọi phải gấp đôi giá trị ban đầu. Trong Pascal, bạn có thể thực hiện việc này bằng cách sử dụng tham chiếu chuyển qua

def <function_name>([<parameters>]):
    <statement(s)>
1

Việc thực thi mã này tạo ra đầu ra sau, xác minh rằng

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
39 thực sự sửa đổi
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 trong môi trường gọi

def <function_name>([<parameters>]):
    <statement(s)>
2

Trong Python, điều này sẽ không hoạt động. Như bạn đã biết, số nguyên trong Python là bất biến, do đó, hàm Python không thể thay đổi đối số số nguyên bằng tác dụng phụ

>>>

def <function_name>([<parameters>]):
    <statement(s)>
3

Tuy nhiên, bạn có thể sử dụng giá trị trả về để có được hiệu ứng tương tự. Chỉ cần viết

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
39 để nó nhận một đối số số nguyên, nhân đôi nó và trả về giá trị nhân đôi. Sau đó, người gọi chịu trách nhiệm về nhiệm vụ sửa đổi giá trị ban đầu

>>>

def <function_name>([<parameters>]):
    <statement(s)>
4

Điều này được cho là thích hợp hơn để sửa đổi bởi tác dụng phụ. Rất rõ ràng rằng

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 đang được sửa đổi trong môi trường cuộc gọi vì người gọi đang tự làm như vậy. Dù sao, đó là lựa chọn duy nhất, bởi vì sửa đổi bằng tác dụng phụ không hoạt động trong trường hợp này

Tuy nhiên, ngay cả trong trường hợp có thể sửa đổi đối số bằng tác dụng phụ, việc sử dụng giá trị trả về vẫn có thể rõ ràng hơn. Giả sử bạn muốn nhân đôi mọi mục trong danh sách. Vì danh sách có thể thay đổi, nên bạn có thể xác định hàm Python để sửa đổi danh sách tại chỗ

>>>

def <function_name>([<parameters>]):
    <statement(s)>
5

Không giống như

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
39 trong ví dụ trước,
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
44 thực sự hoạt động như dự kiến. Nếu tài liệu về hàm nêu rõ rằng nội dung của đối số danh sách đã bị thay đổi, thì đây có thể là một cách triển khai hợp lý

Tuy nhiên, bạn cũng có thể viết

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
44 để chuyển lại danh sách mong muốn bằng giá trị trả về và cho phép người gọi thực hiện phép gán, tương tự như cách viết lại
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
39 trong ví dụ trước

>>>

def <function_name>([<parameters>]):
    <statement(s)>
6

Một trong hai cách tiếp cận hoạt động tốt như nhau. Như thường lệ, đây là vấn đề về phong cách và sở thích cá nhân khác nhau. Các tác dụng phụ không nhất thiết phải hoàn toàn xấu xa và chúng có vị trí của chúng, nhưng vì hầu như mọi thứ đều có thể được trả về từ một hàm, nên điều tương tự cũng có thể được thực hiện thông qua các giá trị trả về.

Danh sách đối số có độ dài thay đổi

Trong một số trường hợp, khi bạn định nghĩa một hàm, bạn có thể không biết trước mình muốn nó nhận bao nhiêu đối số. Ví dụ, giả sử bạn muốn viết một hàm Python để tính giá trị trung bình của một vài giá trị. Bạn có thể bắt đầu với một cái gì đó như thế này

>>>

def <function_name>([<parameters>]):
    <statement(s)>
7

Tất cả đều ổn nếu bạn muốn tính trung bình ba giá trị

>>>

def <function_name>([<parameters>]):
    <statement(s)>
8

However, as you’ve already seen, when positional arguments are used, the number of arguments passed must agree with the number of parameters declared. Clearly then, all isn’t well with this implementation of

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 for any number of values other than three

>>>

def <function_name>([<parameters>]):
    <statement(s)>
9

Bạn có thể thử xác định

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 với các tham số tùy chọn

>>>

<function_name>([<arguments>])
0

Điều này cho phép một số lượng đối số khác nhau được chỉ định. The following calls are at least syntactically correct

<function_name>([<arguments>])
1

Nhưng cách tiếp cận này vẫn gặp phải một số vấn đề. Đối với người mới bắt đầu, nó vẫn chỉ cho phép tối đa năm đối số, không phải là một số tùy ý. Tệ hơn nữa, không có cách nào để phân biệt giữa các đối số đã được chỉ định và những đối số được phép mặc định. Hàm không có cách nào để biết có bao nhiêu đối số thực sự được truyền vào, vì vậy nó không biết chia cho cái gì

>>>

<function_name>([<arguments>])
2

Rõ ràng, điều này cũng sẽ không làm được

Bạn có thể viết

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 để lấy một đối số danh sách

>>>

<function_name>([<arguments>])
3

Ít nhất điều này hoạt động. Nó cho phép một số lượng giá trị tùy ý và tạo ra một kết quả chính xác. Là một phần thưởng bổ sung, nó cũng hoạt động khi đối số là một bộ

>>>

<function_name>([<arguments>])
4

Hạn chế là bước bổ sung phải nhóm các giá trị vào một danh sách hoặc bộ dữ liệu có thể không phải là điều mà người dùng hàm mong đợi và nó không được thanh lịch cho lắm. Whenever you find Python code that looks inelegant, there’s probably a better option

Trong trường hợp này, thực sự có. Python cung cấp một cách để truyền vào một hàm một số lượng đối số khác nhau với việc đóng gói và giải nén bộ đối số bằng cách sử dụng toán tử dấu hoa thị (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50)

Remove ads

Đối số Tuple đóng gói

Khi tên tham số trong định nghĩa hàm Python được đặt trước dấu hoa thị (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50), nó biểu thị việc đóng gói bộ đối số. Mọi đối số tương ứng trong lời gọi hàm được đóng gói thành một đối số mà hàm có thể tham chiếu tới bằng tên tham số đã cho. Đây là một ví dụ

>>>

<function_name>([<arguments>])
5

Trong định nghĩa của

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36, đặc tả tham số
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 biểu thị việc đóng gói bộ. Trong mỗi lệnh gọi tới
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36, các đối số được đóng gói thành một bộ mà hàm có thể tham chiếu tới bằng tên
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
55. Bất kỳ tên nào cũng có thể được sử dụng, nhưng
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
55 thường được chọn đến mức thực tế nó là một tiêu chuẩn

Sử dụng đóng gói tuple, bạn có thể dọn dẹp

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 như thế này

>>>

<function_name>([<arguments>])
6

Tốt hơn nữa, bạn có thể dọn dẹp nó hơn nữa bằng cách thay thế vòng lặp

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
58 bằng hàm Python tích hợp sẵn
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
59, tính tổng các giá trị số trong bất kỳ lần lặp nào

>>>

<function_name>([<arguments>])
7

Bây giờ,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 được viết chính xác và hoạt động như dự kiến

Tuy nhiên, tùy thuộc vào cách mã này sẽ được sử dụng, có thể vẫn còn nhiều việc phải làm. Như đã viết,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
47 sẽ tạo ra một ngoại lệ
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
62 nếu bất kỳ đối số nào không phải là số

>>>

<function_name>([<arguments>])
8

Để mạnh mẽ nhất có thể, bạn nên thêm mã để kiểm tra xem các đối số có thuộc loại phù hợp không. Ở phần sau của loạt bài hướng dẫn này, bạn sẽ học cách nắm bắt các ngoại lệ như

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
62 và xử lý chúng một cách thích hợp. Bạn cũng có thể kiểm tra Ngoại lệ Python. Một lời giới thiệu

Giải nén Tuple đối số

Một hoạt động tương tự có sẵn ở phía bên kia của phương trình trong lệnh gọi hàm Python. Khi một đối số trong lệnh gọi hàm được đặt trước dấu hoa thị (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50), điều đó cho biết đối số đó là một bộ nên được giải nén và chuyển đến hàm dưới dạng các giá trị riêng biệt

>>>

<function_name>([<arguments>])
9

Trong ví dụ này,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
65 trong lệnh gọi hàm chỉ ra rằng
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
66 là một bộ cần được giải nén. Giá trị giải nén
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
84,
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
68 và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
69 lần lượt được gán cho các tham số
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
18 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
19

Mặc dù kiểu giải nén này được gọi là giải nén theo bộ, nhưng nó không chỉ hoạt động với các bộ. Toán tử dấu hoa thị (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50) có thể được áp dụng cho bất kỳ lần lặp nào trong lệnh gọi hàm Python. Ví dụ: một hoặc bộ cũng có thể được giải nén

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
0

Bạn thậm chí có thể sử dụng đóng gói và giải nén tuple cùng một lúc

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
1

Ở đây,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
74 chỉ ra rằng danh sách
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
75 nên được giải nén và các mục được chuyển đến
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 dưới dạng các giá trị riêng lẻ. Đặc tả tham số
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 làm cho các giá trị được đóng gói ngược vào bộ dữ liệu
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
55

Đóng gói từ điển đối số

Python có một toán tử tương tự, dấu hoa thị kép (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
79), có thể được sử dụng với các tham số và đối số của hàm Python để chỉ định việc đóng gói và giải nén từ điển. Trước một tham số trong định nghĩa hàm Python bằng dấu hoa thị kép (
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
79) cho biết rằng các đối số tương ứng, dự kiến ​​là các cặp
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
81, nên được đưa vào từ điển

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
2

Trong trường hợp này, các đối số

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
82,
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
83 và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
84 được đóng gói trong một từ điển mà hàm có thể tham chiếu theo tên
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
85. Một lần nữa, bất kỳ tên nào cũng có thể được sử dụng, nhưng tên đặc biệt
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
85 (viết tắt của từ khóa args) gần như là tiêu chuẩn. Bạn không cần phải tuân theo nó, nhưng nếu bạn làm như vậy, thì bất kỳ ai quen thuộc với các quy ước mã hóa Python sẽ biết ngay ý của bạn

Giải nén từ điển đối số

Giải nén từ điển đối số tương tự như giải nén bộ dữ liệu đối số. Khi dấu hoa thị kép (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
79) đứng trước một đối số trong lệnh gọi hàm Python, nó chỉ định rằng đối số đó là một từ điển cần được giải nén, với các mục kết quả được chuyển đến hàm dưới dạng đối số từ khóa

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
3

Các mục trong từ điển

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
88 được giải nén và chuyển tới
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 làm đối số từ khóa. Vì vậy,
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
90 tương đương với
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
91

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
4

Trên thực tế, hãy kiểm tra điều này

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
5

Ở đây,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
92 tạo một từ điển từ các cặp khóa/giá trị được chỉ định. Sau đó, toán tử dấu hoa thị kép (
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
79) giải nén nó và chuyển các từ khóa tới
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36

Để tất cả chúng cùng nhau

Think of

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 as a variable-length positional argument list, and
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
96 as a variable-length keyword argument list

Ghi chú. Để có cái nhìn khác về

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
96, hãy xem Python args và kwargs. làm sáng tỏ

Tất cả ba—tham số vị trí tiêu chuẩn,

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
96—có thể được sử dụng trong một định nghĩa hàm Python. Nếu vậy, thì chúng nên được chỉ định theo thứ tự đó

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
6

Điều này mang lại sự linh hoạt gần như bạn có thể cần trong một giao diện chức năng

Nhiều lần giải nén trong một lệnh gọi hàm Python

Python phiên bản 3. 5 đã giới thiệu hỗ trợ cho các khái quát hóa giải nén bổ sung, như được nêu trong PEP 448. Một điều mà những cải tiến này cho phép là nhiều lần giải nén trong một lệnh gọi hàm Python

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
7

Bạn cũng có thể chỉ định nhiều lần giải nén từ điển trong lệnh gọi hàm Python

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
8

Ghi chú. Cải tiến này chỉ có trong phiên bản Python 3. 5 hoặc muộn hơn. Nếu bạn thử điều này trong phiên bản cũ hơn, thì bạn sẽ nhận được một ngoại lệ

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
01

Nhân tiện, các toán tử giải nén

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50 và
# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
79 không chỉ áp dụng cho các biến, như trong các ví dụ trên. Bạn cũng có thể sử dụng chúng với các chữ có thể lặp lại

>>>

 1def f():
 2    s = '-- Inside f()'
 3    print(s)
 4
 5print('Before calling f()')
 6f()
 7print('After calling f()')
9

Ở đây, các danh sách theo nghĩa đen

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
04 và
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
05 được chỉ định để giải nén bộ dữ liệu và các từ điển theo nghĩa đen
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
06 và
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
07 được chỉ định để giải nén từ điển

Đối số chỉ từ khóa

Một chức năng Python trong phiên bản 3. x có thể được xác định sao cho nó nhận các đối số chỉ từ khóa. Đây là các đối số chức năng phải được chỉ định bởi từ khóa. Hãy khám phá một tình huống mà điều này có thể có lợi

Giả sử bạn muốn viết một hàm Python nhận một số lượng đối số chuỗi thay đổi, nối chúng lại với nhau và phân tách bằng dấu chấm (

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
08) và in chúng ra bàn điều khiển. Một cái gì đó như thế này sẽ làm để bắt đầu

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
0

Như hiện tại, tiền tố đầu ra được mã hóa cứng thành chuỗi

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
09. Điều gì sẽ xảy ra nếu bạn muốn sửa đổi hàm để chấp nhận điều này làm đối số, để người dùng có thể chỉ định điều gì khác?

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
1

Điều này hoạt động như quảng cáo, nhưng có một vài điều không mong muốn về giải pháp này

  1. Chuỗi

    def read_file():
        # Code to read file in
        <statement>
        <statement>
        <statement>
        <statement>
    
    def process_file():
        # Code to process file
        <statement>
        <statement>
        <statement>
        <statement>
    
    def write_file():
        # Code to write file out
        <statement>
        <statement>
        <statement>
        <statement>
    
    
    # Main program
    read_file()
    process_file()
    write_file()
    
    10 được gộp chung với các chuỗi cần nối. Chỉ cần nhìn vào lệnh gọi hàm, không rõ ràng rằng đối số đầu tiên được xử lý khác với phần còn lại. Để biết điều đó, bạn phải quay lại và xem định nghĩa hàm

  2. def read_file():
        # Code to read file in
        <statement>
        <statement>
        <statement>
        <statement>
    
    def process_file():
        # Code to process file
        <statement>
        <statement>
        <statement>
        <statement>
    
    def write_file():
        # Code to write file out
        <statement>
        <statement>
        <statement>
        <statement>
    
    
    # Main program
    read_file()
    process_file()
    write_file()
    
    10 không phải là tùy chọn. Nó luôn phải được đưa vào và không có cách nào để giả định một giá trị mặc định

Bạn có thể nghĩ rằng bạn có thể khắc phục vấn đề thứ hai bằng cách chỉ định một tham số có giá trị mặc định, có lẽ như thế này

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
2

Thật không may, điều này không hoạt động hoàn toàn đúng.

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
10 là một tham số vị trí, vì vậy trình thông dịch giả định rằng đối số đầu tiên được chỉ định trong lệnh gọi hàm là tiền tố đầu ra dự định. Điều này có nghĩa là không có cách nào để bỏ qua nó và lấy giá trị mặc định

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
3

Điều gì sẽ xảy ra nếu bạn cố gắng chỉ định

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
10 làm đối số từ khóa?

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
4

Như bạn đã thấy trước đây, khi cả hai loại đối số được đưa ra, tất cả các đối số vị trí phải xuất hiện trước bất kỳ đối số từ khóa nào

Tuy nhiên, bạn cũng không thể chỉ định nó lần cuối

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
5

Một lần nữa,

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
10 là một tham số vị trí, vì vậy nó được gán đối số đầu tiên được chỉ định trong lệnh gọi (trong trường hợp này là ____12_______15). Sau đó, khi nó được chỉ định lại làm đối số từ khóa ở cuối, Python nghĩ rằng nó đã được chỉ định hai lần

Các thông số chỉ dành cho từ khóa giúp giải quyết tình trạng khó xử này. Trong định nghĩa hàm, chỉ định

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 để biểu thị số lượng biến đối số vị trí, sau đó chỉ định
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
10 sau đó

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
6

Trong trường hợp đó,

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
10 trở thành tham số chỉ từ khóa. Giá trị của nó sẽ không bao giờ được lấp đầy bởi một đối số vị trí. Nó chỉ có thể được chỉ định bởi một đối số từ khóa được đặt tên

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
7

Lưu ý rằng điều này chỉ có thể thực hiện được trong Python 3. Trong phiên bản 2. x của Python, chỉ định các tham số bổ sung sau tham số đối số biến

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
53 gây ra lỗi

Đối số chỉ từ khóa cho phép hàm Python nhận một số lượng đối số khác nhau, theo sau là một hoặc nhiều tùy chọn bổ sung làm đối số từ khóa. Nếu bạn muốn sửa đổi

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
20 để ký tự phân tách cũng có thể được chỉ định tùy ý, thì bạn có thể thêm một đối số bổ sung chỉ dành cho từ khóa

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
8

Nếu tham số chỉ từ khóa được cung cấp giá trị mặc định trong định nghĩa hàm (như trong ví dụ trên) và từ khóa bị bỏ qua khi hàm được gọi, thì giá trị mặc định sẽ được cung cấp

>>>

C:\Users\john\Documents\Python\doc>python foo.py
Before calling f()
-- Inside f()
After calling f()
9

Mặt khác, nếu tham số không được cung cấp giá trị mặc định, thì tham số đó sẽ trở thành bắt buộc và việc không chỉ định tham số sẽ dẫn đến lỗi

>>>

>>> def f():
..     pass
...
>>> f()
0

Điều gì sẽ xảy ra nếu bạn muốn xác định một hàm Python chỉ nhận một đối số từ khóa nhưng không nhận một số lượng đối số vị trí khác nhau?

>>>

>>> def f():
..     pass
...
>>> f()
1

Nếu bạn muốn biến

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
21 thành tham số chỉ có từ khóa, thì bạn có thể thêm tham số đối số biến giả không liên quan và chỉ cần bỏ qua tham số đó

>>>

>>> def f():
..     pass
...
>>> f()
2

Vấn đề với giải pháp này là

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
22 hấp thụ mọi đối số vị trí không liên quan có thể được đưa vào

>>>

>>> def f():
..     pass
...
>>> f()
3

Trong ví dụ này, không nên có đối số bổ sung (vì chính đối số đó đã thông báo). Thay vì thành công một cách lặng lẽ, nó thực sự sẽ dẫn đến một lỗi. Thực tế là nó không phải là lộn xộn nhất. Tệ nhất, nó có thể gây ra một kết quả có vẻ sai lệch

>>>

>>> def f():
..     pass
...
>>> f()
4

Để khắc phục điều này, phiên bản 3 cho phép tham số đối số biến trong định nghĩa hàm Python chỉ là dấu hoa thị (

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50), với tên được bỏ qua

>>>

>>> def f():
..     pass
...
>>> f()
5

Tham số đối số biến trần

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
50 chỉ ra rằng không có bất kỳ tham số vị trí nào nữa. Hành vi này tạo ra các thông báo lỗi thích hợp nếu các thông báo lỗi bổ sung được chỉ định. Nó cho phép các tham số chỉ từ khóa theo dõi

Đối số chỉ vị trí

Kể từ Python 3. 8, các tham số chức năng cũng có thể được khai báo chỉ theo vị trí, nghĩa là các đối số tương ứng phải được cung cấp theo vị trí và không thể được chỉ định bằng từ khóa

Để chỉ định một số tham số là chỉ vị trí, bạn chỉ định dấu gạch chéo (

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
25) trong danh sách tham số của định nghĩa hàm. Bất kỳ tham số nào ở bên trái dấu gạch chéo (
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
25) phải được chỉ định theo vị trí. Ví dụ: trong định nghĩa hàm sau,
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
17 và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
18 là các tham số chỉ vị trí, nhưng
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
19 có thể được chỉ định bằng từ khóa

>>>

>>> def f():
..     pass
...
>>> f()
6

Điều này có nghĩa là các cuộc gọi sau là hợp lệ

>>>

>>> def f():
..     pass
...
>>> f()
7

Tuy nhiên, cuộc gọi sau tới

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 không hợp lệ

>>>

>>> def f():
..     pass
...
>>> f()
8

Cả hai chỉ định vị trí và chỉ từ khóa đều có thể được sử dụng trong cùng một định nghĩa hàm

>>>

>>> def f():
..     pass
...
>>> f()
9

trong ví dụ này

  • >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    17 và
    >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    18 chỉ là vị trí
  • # Main program
    
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>
    
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>
    
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>
    
    75 và
    def read_file():
        # Code to read file in
        <statement>
        <statement>
        <statement>
        <statement>
    
    def process_file():
        # Code to process file
        <statement>
        <statement>
        <statement>
        <statement>
    
    def write_file():
        # Code to write file out
        <statement>
        <statement>
        <statement>
        <statement>
    
    
    # Main program
    read_file()
    process_file()
    write_file()
    
    34 chỉ là từ khóa
  • >>> a = ['foo', 'bar', 'baz', 'qux']
    >>> len(a)
    4
    
    19 và
    def read_file():
        # Code to read file in
        <statement>
        <statement>
        <statement>
        <statement>
    
    def process_file():
        # Code to process file
        <statement>
        <statement>
        <statement>
        <statement>
    
    def write_file():
        # Code to write file out
        <statement>
        <statement>
        <statement>
        <statement>
    
    
    # Main program
    read_file()
    process_file()
    write_file()
    
    36 có thể được chỉ định theo vị trí hoặc theo từ khóa

Để biết thêm thông tin về các tham số chỉ vị trí, hãy xem phần

tài liệu

Khi câu lệnh đầu tiên trong phần thân của hàm Python là một chuỗi ký tự, nó được gọi là chuỗi tài liệu của hàm. Một chuỗi tài liệu được sử dụng để cung cấp tài liệu cho một chức năng. Nó có thể chứa mục đích của hàm, những đối số mà hàm nhận, thông tin về giá trị trả về hoặc bất kỳ thông tin nào khác mà bạn cho là hữu ích

Sau đây là một ví dụ về định nghĩa hàm với chuỗi tài liệu

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
00

Về mặt kỹ thuật, các chuỗi tài liệu có thể sử dụng bất kỳ cơ chế trích dẫn nào của Python, nhưng quy ước được khuyến nghị là trích dẫn ba lần bằng cách sử dụng các ký tự trích dẫn kép (

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
37), như minh họa ở trên. Nếu chuỗi tài liệu nằm trên một dòng, thì dấu ngoặc kép đóng phải nằm trên cùng một dòng với dấu ngoặc kép mở

Multi-line docstrings are used for lengthier documentation. Một chuỗi tài liệu nhiều dòng phải bao gồm một dòng tóm tắt, theo sau là một dòng trống, tiếp theo là một mô tả chi tiết hơn. Các trích dẫn đóng phải nằm trên một dòng

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
01

Định dạng chuỗi tài liệu và quy ước ngữ nghĩa được trình bày chi tiết trong PEP 257

Khi một chuỗi tài liệu được xác định, trình thông dịch Python sẽ gán nó cho một thuộc tính đặc biệt của hàm có tên là

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
38. Thuộc tính này là một trong những bộ định danh chuyên biệt trong Python, đôi khi được gọi là thuộc tính ma thuật hoặc phương thức ma thuật vì chúng cung cấp chức năng ngôn ngữ đặc biệt

Ghi chú. Các thuộc tính này cũng được gọi bằng các thuộc tính dunder biệt danh đầy màu sắc và các phương thức dunder. Từ dunder kết hợp d từ double và under từ ký tự gạch dưới (

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
39). Bạn sẽ gặp nhiều thuộc tính và phương thức khác trong các hướng dẫn trong tương lai của loạt bài này

Bạn có thể truy cập chuỗi tài liệu của hàm bằng biểu thức

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
40. Các tài liệu cho các ví dụ trên có thể được hiển thị như sau

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
02

Trong trình thông dịch Python tương tác, bạn có thể nhập

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
41 để hiển thị chuỗi tài liệu cho
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
27

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
03

Việc chỉ định một chuỗi tài liệu cho từng hàm Python mà bạn xác định được coi là một phương pháp mã hóa tốt. Để biết thêm về docstrings, hãy xem

Chú thích hàm Python

Kể từ phiên bản 3. 0, Python cung cấp một tính năng bổ sung để ghi lại một hàm được gọi là chú thích hàm. Chú thích cung cấp một cách để đính kèm siêu dữ liệu vào các tham số của hàm và trả về giá trị

Để thêm chú thích vào tham số hàm Python, hãy chèn dấu hai chấm (

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
29) theo sau bởi bất kỳ biểu thức nào sau tên tham số trong định nghĩa hàm. Để thêm chú thích vào giá trị trả về, hãy thêm các ký tự
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
44 và bất kỳ biểu thức nào giữa dấu ngoặc đơn đóng của danh sách tham số và dấu hai chấm kết thúc tiêu đề hàm. Đây là một ví dụ

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
04

Chú thích cho tham số

# Main program

# Code to read file in
<statement>
<statement>
<statement>
<statement>

# Code to process file
<statement>
<statement>
<statement>
<statement>

# Code to write file out
<statement>
<statement>
<statement>
<statement>
75 là chuỗi
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
46, cho
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
34 là chuỗi
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
48 và cho giá trị trả về của hàm là chuỗi
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
49

Trình thông dịch Python tạo một từ điển từ các chú thích và gán chúng cho một thuộc tính dunder đặc biệt khác của hàm có tên là

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
50. Các chú thích cho hàm Python
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 hiển thị ở trên có thể được hiển thị như sau

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
05

Các phím cho các tham số là tên tham số. Chìa khóa cho giá trị trả về là chuỗi

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
52

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
06

Lưu ý rằng các chú thích không bị hạn chế đối với các giá trị chuỗi. Chúng có thể là bất kỳ biểu thức hoặc đối tượng nào. Ví dụ: bạn có thể chú thích bằng các đối tượng kiểu

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
07

Chú thích thậm chí có thể là một đối tượng tổng hợp như từ điển hoặc từ điển, vì vậy có thể đính kèm nhiều mục siêu dữ liệu vào tham số và trả về giá trị

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
08

Trong ví dụ trên, một chú thích được gắn vào tham số

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
53 và giá trị trả về. Mỗi chú thích là một từ điển chứa mô tả chuỗi và đối tượng kiểu

Nếu bạn muốn gán giá trị mặc định cho tham số có chú thích, thì giá trị mặc định sẽ nằm sau chú thích

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
09

Chú thích làm gì? . Họ chỉ là loại ở đó. Hãy xem lại một trong những ví dụ ở trên, nhưng với một vài sửa đổi nhỏ

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
10

Những gì đang xảy ra ở đây? . Nhưng cuộc gọi tiếp theo tới

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36 phá vỡ tất cả các quy tắc. Các đối số lần lượt là
>>> any([False, False, False])
False
>>> any([False, True, False])
True

>>> any(['bar' == 'baz', len('foo') == 4, 'qux' in {'foo', 'bar', 'baz'}])
False
>>> any(['bar' == 'baz', len('foo') == 3, 'qux' in {'foo', 'bar', 'baz'}])
True
80 và
def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
57 và giá trị trả về là một bộ. Tuy nhiên, thông dịch viên cho phép tất cả trượt mà không phàn nàn gì cả

Chú thích không áp đặt bất kỳ hạn chế ngữ nghĩa nào đối với mã. Chúng chỉ đơn giản là các bit siêu dữ liệu được đính kèm với các tham số hàm Python và giá trị trả về. Python cẩn thận cất chúng vào một từ điển, gán từ điển cho thuộc tính dunder

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
50 của hàm, và thế là xong. Chú thích là hoàn toàn tùy chọn và hoàn toàn không có bất kỳ tác động nào đến việc thực thi hàm Python

To quote Amahl in Amahl and the Night Visitors, “What’s the use of having it then?”

Đối với người mới bắt đầu, chú thích tạo tài liệu tốt. Tất nhiên, bạn có thể chỉ định thông tin tương tự trong chuỗi tài liệu, nhưng việc đặt nó trực tiếp trong định nghĩa hàm sẽ làm rõ hơn. Các loại đối số và giá trị trả về hiển thị rõ ràng đối với tiêu đề hàm như thế này

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
11

Cấp, trình thông dịch không bắt buộc tuân thủ các loại được chỉ định, nhưng ít nhất chúng rõ ràng đối với người đọc định nghĩa hàm

Lặn sâu. Thực thi kiểm tra loại

Nếu muốn, bạn có thể thêm mã để thực thi các loại được chỉ định trong chú thích hàm. Đây là một hàm kiểm tra loại thực tế của từng đối số so với những gì được chỉ định trong chú thích cho tham số tương ứng. Nó hiển thị

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
23 nếu chúng khớp và
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
24 nếu chúng không khớp

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
12

(Mô-đun

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
64 chứa các hàm lấy thông tin hữu ích về các đối tượng trực tiếp—trong trường hợp này là hàm
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
36. )

Nếu muốn, một hàm được xác định giống như hàm ở trên có thể thực hiện một số loại hành động khắc phục khi nó phát hiện ra rằng các đối số được truyền vào không tuân theo các loại được chỉ định trong chú thích

Trên thực tế, sơ đồ sử dụng chú thích để thực hiện kiểm tra kiểu tĩnh trong Python được mô tả trong PEP 484. Có sẵn một trình kiểm tra kiểu tĩnh miễn phí dành cho Python có tên là mypy, được xây dựng trên đặc tả PEP 484

Cũng có một lợi ích khác khi sử dụng chú thích. Định dạng tiêu chuẩn hóa trong đó thông tin chú thích được lưu trữ trong thuộc tính

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
50 phù hợp với việc phân tích chữ ký hàm bằng các công cụ tự động

Khi nói đến nó, các chú thích không có gì đặc biệt kỳ diệu. Bạn thậm chí có thể định nghĩa của riêng mình mà không cần cú pháp đặc biệt mà Python cung cấp. Đây là một định nghĩa hàm Python với các chú thích đối tượng kiểu được đính kèm với các tham số và giá trị trả về

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
13

Sau đây về cơ bản là chức năng tương tự, với từ điển

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
50 được xây dựng thủ công

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
14

Hiệu ứng giống hệt nhau trong cả hai trường hợp, nhưng hiệu ứng đầu tiên hấp dẫn hơn và dễ đọc hơn ngay từ cái nhìn đầu tiên

Trên thực tế, thuộc tính

def read_file():
    # Code to read file in
    <statement>
    <statement>
    <statement>
    <statement>

def process_file():
    # Code to process file
    <statement>
    <statement>
    <statement>
    <statement>

def write_file():
    # Code to write file out
    <statement>
    <statement>
    <statement>
    <statement>


# Main program
read_file()
process_file()
write_file()
50 không khác biệt đáng kể so với hầu hết các thuộc tính khác của hàm. Ví dụ, nó có thể được sửa đổi động. Bạn có thể chọn sử dụng thuộc tính giá trị trả về để đếm số lần một hàm được thực thi

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> len(a)
4
15

Chú thích hàm Python không gì khác hơn là từ điển siêu dữ liệu. Điều xảy ra là bạn có thể tạo chúng bằng cú pháp thuận tiện được trình thông dịch hỗ trợ. Họ là bất cứ điều gì bạn chọn để làm cho họ

Phần kết luận

Khi các ứng dụng phát triển lớn hơn, việc mô đun hóa mã bằng cách chia mã thành các chức năng nhỏ hơn với kích thước có thể quản lý ngày càng trở nên quan trọng. Bây giờ bạn hy vọng có tất cả các công cụ bạn cần để làm điều này

Bạn đã học

  • Cách tạo hàm do người dùng định nghĩa trong Python
  • Một số cách khác nhau để bạn có thể truyền đối số cho một hàm
  • Cách bạn có thể trả lại dữ liệu từ một chức năng cho người gọi nó
  • Cách thêm tài liệu vào các chức năng bằng tài liệu và chú thích

Tiếp theo trong loạt bài này là hai hướng dẫn về tìm kiếm và khớp mẫu. Bạn sẽ có cái nhìn sâu hơn về mô-đun Python có tên là re, mô-đun này chứa chức năng tìm kiếm và so khớp bằng cách sử dụng cú pháp mẫu linh hoạt được gọi là biểu thức chính quy

« Kỹ thuật định dạng chuỗi Python

Biểu thức chính quy. Regex trong Python (Phần 1) »

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Định nghĩa và gọi hàm Python

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Làm cách nào để viết một hàm trong Python?

Gửi cho tôi thủ thuật Python »

Giới thiệu về John Sturtz

Làm cách nào để viết một hàm trong Python?
Làm cách nào để viết một hàm trong Python?

John là một Pythonista cuồng nhiệt và là thành viên của nhóm hướng dẫn Real Python

» Thông tin thêm về John


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Làm cách nào để viết một hàm trong Python?

Aldren

Làm cách nào để viết một hàm trong Python?

Jaya

Làm cách nào để viết một hàm trong Python?

Joanna

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Ví dụ về hàm Python là gì?

Functions in python are defined using the block keyword "def", followed with the function's name as the block's name. Ví dụ. def my_function(). print("Hello From My Function. ")

Hàm def() trong Python là gì?

def is the keyword for defining a function . Tên hàm được theo sau bởi (các) tham số trong (). The colon . báo hiệu sự bắt đầu của thân hàm, được đánh dấu bằng dấu thụt đầu dòng. Inside the function body, the return statement determines the value to be returned.

Chúng ta có thể tạo chức năng trong Python không?

Python gives you the ability to create your own custom functions . There are a few things you need to understand, but it's not that hard to do. So let's get started. Các chức năng tùy chỉnh là một cách tuyệt vời để đóng gói độc đáo các khối mã có thể tái sử dụng.

Làm thế nào để viết một phương thức trong Python?

Để tạo một phương thức làm phương thức lớp, thêm trình trang trí @classmethod trước định nghĩa phương thức và thêm cls làm tham số đầu tiên cho phương thức . Trình trang trí @classmethod là một trình trang trí chức năng tích hợp. Trong Python, chúng tôi sử dụng trình trang trí @classmethod để khai báo một phương thức dưới dạng một phương thức lớp.