Tham số mặc định trong Python là giá trị mặc định được gán cho tham số hàm. Nếu tôi định nghĩa hàm
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
1 với tham số COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
2, nó đảm bảo rằng nếu không có giá trị nào được chuyển cho tham số này, thì giá trị mặc định COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
3 sẽ được sử dụngCOPYdef foo[bar=3]:
return bar + 2
n = foo[] # returns 5
n = foo[10] # return 12
Lưu ý chính là các tham số mặc định chỉ được đánh giá một lần và có thể gây ra sự cố khi một hàm được gọi nhiều lần
Tại sao một mảng trống làm tham số mặc định trong Python có thể gây ra sự cố?
Vì các tham số chỉ được đánh giá MỘT LẦN, nên việc trả lại hoặc sử dụng một mảng có tham số mặc định có thể tạo ra sự cố, vì giá trị từ lệnh gọi trước có thể được sử dụng lại trong lệnh gọi sau
Hãy xem xét một ví dụ cụ thể
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
Khi thực thi đoạn mã trên, ở lần gọi thứ hai, giá trị của lần gọi đầu tiên đã được sử dụng lại, điều này [gần như] không bao giờ là điều chúng ta muốn
COPY$ python pythoncode.py
[42]
[42, 42]
Đây là một vấn đề phổ biến trong mã Python đã được ghi lại [xem Gotchas chung cho Python]
Làm cách nào để tránh gặp sự cố với một mảng trống làm tham số mặc định trong Python?
Ý tưởng là không sử dụng một mảng làm tham số mặc định và thay vào đó là
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
4. Sau đó, bên trong hàm, chúng tôi kiểm tra xem một giá trị đã được truyền chưa và gán nóCó phiên bản sửa lỗi của mã được hiển thị ở trên
COPYimport typing
def foo[bar: typing.Optional[typing.List[int]]=None]:
if bar is None:
res = []
else:
res = bar
res.append[42]
return res
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
Khi thực thi đoạn mã, chúng ta có kết quả chính xác
COPY$ python pythoncode.py
[42]
[42]
Tự động làm trống mảng làm tham số mặc định trong Python
Codiga cung cấp các plugin và tích hợp IDE với GitHub, GitLab hoặc Bitbucket để phát hiện các mảng trống làm tham số mặc định. Phân tích mã tĩnh Codiga phát hiện vấn đề này trực tiếp trong IDE hoặc đánh giá mã của bạn
Cụ thể, quy tắc phân tích này đưa ra cảnh báo mỗi khi có một mảng trống làm tham số mặc định trong định nghĩa hàm
Tránh tham số mảng trống
Để sử dụng quy tắc này một cách nhất quán, tất cả những gì bạn cần làm là cài đặt tích hợp trong IDE [đối với Mã VS hoặc JetBrains] hoặc hệ thống quản lý mã và thêm tệp
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
0 vào thư mục gốc của hồ sơ của bạn với nội dung sauCOPYrulesets:
- python-security
Sau đó, nó sẽ kiểm tra tất cả mã Python của bạn dựa trên hơn 100 quy tắc phát hiện mã không an toàn và không an toàn, đồng thời đề xuất các bản sửa lỗi cho từng quy tắc đó
Liệu lưu trữ dữ liệu đa chiều theo thứ tự hàng chính [kiểu C] hay cột chính [kiểu Fortran] trong bộ nhớ
like array_like, tùy chọnĐối tượng tham chiếu để cho phép tạo các mảng không phải là mảng NumPy. Nếu một mảng giống như được chuyển vào dưới dạng
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
5 hỗ trợ giao thức COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
6, thì kết quả sẽ được xác định bởi nó. Trong trường hợp này, nó đảm bảo việc tạo ra một đối tượng mảng tương thích với đối tượng được truyền qua đối số nàyMới trong phiên bản 1. 20. 0
Trả về . ra ndarrayMảng dữ liệu chưa được khởi tạo [tùy ý] của hình dạng, kiểu và thứ tự đã cho. Mảng đối tượng sẽ được khởi tạo thành Không có
Xem thêm
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
7Trả về một mảng trống với hình dạng và loại đầu vào
COPYimport typing
def foo[bar: typing.List[int] = []]:
bar.append[42]
return bar
l1 = foo[]
print[l1]
l2 = foo[]
print[l2]
8Trả lại một giá trị cài đặt mảng mới thành một
>>> np.empty[[2, 2], dtype=int] array[[[-1073741821, -1067949133], [ 496041986, 19249760]]] #uninitialized0
Trả lại giá trị cài đặt mảng mới về 0
>>> np.empty[[2, 2], dtype=int] array[[[-1073741821, -1067949133], [ 496041986, 19249760]]] #uninitialized1
Trả về một mảng mới có hình dạng đã cho chứa đầy giá trị
ghi chú
>>> np.empty[[2, 2], dtype=int] array[[[-1073741821, -1067949133], [ 496041986, 19249760]]] #uninitialized2, không giống như
>>> np.empty[[2, 2], dtype=int] array[[[-1073741821, -1067949133], [ 496041986, 19249760]]] #uninitialized0, không đặt các giá trị mảng thành 0 và do đó có thể nhanh hơn một chút. Mặt khác, nó yêu cầu người dùng đặt tất cả các giá trị trong mảng theo cách thủ công và nên thận trọng khi sử dụng