Hướng dẫn dùng casting python python


Specify a Variable Type

There may be times when you want to specify a type on to a variable. This can be done with casting. Python is an object-orientated language, and as such it uses classes to define data types, including its primitive types.

Casting in python is therefore done using constructor functions:

  • int() - constructs an integer number from an integer literal, a float literal (by removing all decimals), or a string literal (providing the string represents a whole number)
  • float() - constructs a float number from an integer literal, a float literal or a string literal (providing the string represents a float or an integer)
  • str() - constructs a string from a wide variety of data types, including strings, integer literals and float literals

Example

Integers:

x = int(1)   # x will be 1
y = int(2.8) # y will be 2
z = int("3") # z will be 3

Try it Yourself »

Example

Floats:

x = float(1)     # x will be 1.0
y = float(2.8)   # y will be 2.8
z = float("3")   # z will be 3.0
w = float("4.2") # w will be 4.2

Try it Yourself »

Example

Strings:

x = str("s1") # x will be 's1'
y = str(2)    # y will be '2'
z = str(3.0)  # z will be '3.0'

Try it Yourself »


Specify a Variable Type

There may be times when you want to specify a type on to a variable. This can be done with casting. Python is an object-orientated language, and as such it uses classes to define data types, including its primitive types.

Nội dung chính

  • Specify a Variable Type
  • Cách tốt nhất để kiểm tra nếu một danh sách trống
  • Câu trả lời ngắn:
  • Kháng cáo lên thẩm quyền
  • Giải trình
  • Làm những gì Pythonic thường mang lại hiệu quả:
  • Bằng chứng từ nguồn C và tài liệu

Casting in python is therefore done using constructor functions:

  • int() - constructs an integer number from an integer literal, a float literal (by removing all decimals), or a string literal (providing the string represents a whole number)
  • float() - constructs a float number from an integer literal, a float literal or a string literal (providing the string represents a float or an integer)
  • str() - constructs a string from a wide variety of data types, including strings, integer literals and float literals

Example

Integers:

x = int(1)   # x will be 1
y = int(2.8) # y will be 2
z = int("3") # z will be 3

Try it Yourself »

Example

Floats:

x = float(1)     # x will be 1.0
y = float(2.8)   # y will be 2.8
z = float("3")   # z will be 3.0
w = float("4.2") # w will be 4.2

Try it Yourself »

Example

Strings:

x = str("s1") # x will be 's1'
y = str(2)    # y will be '2'
z = str(3.0)  # z will be '3.0'

Try it Yourself »

Cách tốt nhất để kiểm tra nếu một danh sách trống

Ví dụ: nếu được thông qua như sau:

a = []

Làm thế nào để tôi kiểm tra xem a có trống không?

Câu trả lời ngắn:

Đặt danh sách trong ngữ cảnh boolean (ví dụ: với một câu lệnh ifhoặc while). Nó sẽ kiểm tra Falsenếu nó trống, và Truenếu không. Ví dụ:

if not a:                           # do this!
    print('a is an empty list')

Kháng cáo lên thẩm quyền

PEP 8 , hướng dẫn kiểu Python chính thức cho mã Python trong thư viện chuẩn của Python, khẳng định:

Đối với các chuỗi, (chuỗi, danh sách, bộ dữ liệu), sử dụng thực tế là các chuỗi trống là sai.

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

Chúng ta nên kỳ vọng rằng mã thư viện chuẩn phải có hiệu suất và chính xác nhất có thể. Nhưng tại sao lại như vậy, và tại sao chúng ta cần hướng dẫn này?

Giải trình

Tôi thường thấy mã như thế này từ các lập trình viên có kinh nghiệm mới biết về Python:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

Và người dùng ngôn ngữ lười biếng có thể bị cám dỗ để làm điều này:

if a == []:                         # Don't do this!
    print('a is an empty list')

Đây là chính xác trong các ngôn ngữ khác tương ứng của họ. Và điều này thậm chí còn đúng về mặt ngữ nghĩa trong Python.

Nhưng chúng tôi coi đó là un-Pythonic vì Python hỗ trợ các ngữ nghĩa này trực tiếp trong giao diện của đối tượng danh sách thông qua cưỡng chế boolean.

Từ các tài liệu (và lưu ý cụ thể bao gồm danh sách trống, []):

Theo mặc định, một đối tượng được coi là đúng trừ khi lớp của nó định nghĩa một __bool__()phương thức trả về Falsehoặc một __len__()phương thức trả về 0, khi được gọi với đối tượng. Dưới đây là hầu hết các đối tượng tích hợp được coi là sai:

  • hằng được định nghĩa là sai: NoneFalse.
  • zero của bất kỳ loại số: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • chuỗi rỗng và bộ sưu tập: '', (), [], {}, set(),range(0)

Và tài liệu datamodel:

object.__bool__(self)

Được gọi để thực hiện kiểm tra giá trị thật và hoạt động tích hợp bool(); nên trả lại Falsehoặc True. Khi phương thức này không được định nghĩa, __len__()được gọi, nếu nó được xác định và đối tượng được coi là đúng nếu kết quả của nó là khác không. Nếu một lớp định nghĩa không phải __len__() cũng không __bool__(), tất cả các thể hiện của nó được coi là đúng.

object.__len__(self)

Được gọi để thực hiện chức năng tích hợp len(). Nên trả về độ dài của đối tượng, một số nguyên> = 0. Ngoài ra, một đối tượng không xác định __bool__()phương thức và __len__()phương thức trả về 0 được coi là sai trong ngữ cảnh Boolean.

Vì vậy, thay vì điều này:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

hoặc này:

if a == []:                     # Don't do this!
    print('a is an empty list')

Làm cái này:

if not a:
    print('a is an empty list')

Làm những gì Pythonic thường mang lại hiệu quả:

Nó có trả hết không? (Lưu ý rằng ít thời gian hơn để thực hiện một thao tác tương đương sẽ tốt hơn :)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

Đối với tỷ lệ, đây là chi phí gọi hàm và xây dựng và trả về một danh sách trống, mà bạn có thể trừ vào chi phí của kiểm tra trống rỗng được sử dụng ở trên:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

Chúng ta thấy rằng một trong hai kiểm tra chiều dài với các chức năng được xây dựng trong lenso với 0 hoặc kiểm tra đối với một danh sách rỗng là nhiều ít performant hơn bằng cách sử dụng cú pháp dựng sẵn của ngôn ngữ như tài liệu.

Tại sao?

Đối với len(a) == 0kiểm tra:

Python đầu tiên phải kiểm tra toàn cầu để xem lencó bị bóng không.

Sau đó, nó phải gọi hàm, tải 0và thực hiện so sánh đẳng thức trong Python (thay vì với C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

Và đối với [] == []nó, nó phải xây dựng một danh sách không cần thiết và sau đó, một lần nữa, thực hiện thao tác so sánh trong máy ảo của Python (trái ngược với C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

Cách "Pythonic" là một kiểm tra đơn giản và nhanh hơn nhiều vì độ dài của danh sách được lưu trong bộ đệm của đối tượng:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

Bằng chứng từ nguồn C và tài liệu

PyVarObject

Đây là một phần mở rộng của trường PyObjectthêm ob_size. Điều này chỉ được sử dụng cho các đối tượng có một số khái niệm về chiều dài. Loại này không thường xuất hiện trong API Python / C. Nó tương ứng với các trường được xác định bởi sự mở rộng của PyObject_VAR_HEADmacro.

Từ nguồn c trong Bao gồm / listobject.h :

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

Tôi rất thích nghiên cứu về điều này và tôi dành nhiều thời gian để quản lý câu trả lời của mình. Nếu bạn nghĩ rằng tôi đang để lại một cái gì đó, xin vui lòng cho tôi biết trong một nhận xét.

122 hữu ích 2 bình luận chia sẻ