Lớp Python trả về mảng

Phân lớp ndarray tương đối đơn giản, nhưng nó có một số phức tạp so với các đối tượng Python khác. Trên trang này, chúng tôi giải thích cơ chế cho phép bạn phân lớp ndarray và ý nghĩa của việc triển khai phân lớp

ndarrays và tạo đối tượng

Việc phân lớp ndarray phức tạp bởi thực tế là các thể hiện mới của các lớp ndarray có thể xuất hiện theo ba cách khác nhau. đó là

  1. cuộc gọi hàm tạo rõ ràng - như trong

    >>> class C:
    >>>     def __new__(cls, *args):
    >>>         print('Cls in __new__:', cls)
    >>>         print('Args in __new__:', args)
    >>>         # The `object` type __new__ method takes a single argument.
    >>>         return object.__new__(cls)
    >>>     def __init__(self, *args):
    >>>         print('type(self) in __init__:', type(self))
    >>>         print('Args in __init__:', args)
    
    5. Đây là cách thông thường để tạo phiên bản Python

  2. Xem truyền - truyền một ndarray hiện có dưới dạng một lớp con nhất định

  3. Mới từ mẫu - tạo phiên bản mới từ phiên bản mẫu. Các ví dụ bao gồm trả về các lát từ một mảng được phân lớp, tạo các kiểu trả về từ ufunc và sao chép các mảng. Xem để biết thêm chi tiết

Hai cái cuối cùng là đặc điểm của ndarrays - để hỗ trợ những thứ như cắt mảng. Sự phức tạp của việc phân lớp ndarray là do cơ chế numpy phải hỗ trợ hai lộ trình tạo cá thể sau này

Khi nào sử dụng phân lớp

Bên cạnh sự phức tạp bổ sung của việc phân lớp con một mảng NumPy, các lớp con có thể gặp phải hành vi không mong muốn vì một số hàm có thể chuyển đổi lớp con thành lớp cơ sở và “quên” bất kỳ thông tin bổ sung nào liên quan đến lớp con. Điều này có thể dẫn đến hành vi đáng ngạc nhiên nếu bạn sử dụng các phương thức hoặc hàm NumPy mà bạn chưa kiểm tra rõ ràng

Mặt khác, so với các cách tiếp cận khả năng tương tác khác, phân lớp có thể hữu ích vì nhiều thứ sẽ “hoạt động bình thường”

Điều này có nghĩa là phân lớp có thể là một cách tiếp cận thuận tiện và trong một thời gian dài nó cũng thường là cách tiếp cận khả dụng duy nhất. Tuy nhiên, NumPy hiện cung cấp các giao thức tương tác bổ sung được mô tả trong “”. Đối với nhiều trường hợp sử dụng, các giao thức tương tác này giờ đây có thể phù hợp hơn hoặc bổ sung cho việc sử dụng phân lớp

Phân lớp có thể phù hợp nếu

  • bạn bớt lo lắng về khả năng bảo trì hoặc người dùng khác ngoài chính bạn. Lớp con sẽ triển khai nhanh hơn và khả năng tương tác bổ sung có thể được thêm vào “khi cần”. Và với ít người dùng, những bất ngờ có thể xảy ra không phải là vấn đề

  • bạn không nghĩ rằng đó là vấn đề nếu thông tin phân lớp bị bỏ qua hoặc bị mất âm thầm. Một ví dụ là

    >>> class C:
    >>>     def __new__(cls, *args):
    >>>         print('Cls in __new__:', cls)
    >>>         print('Args in __new__:', args)
    >>>         # The `object` type __new__ method takes a single argument.
    >>>         return object.__new__(cls)
    >>>     def __init__(self, *args):
    >>>         print('type(self) in __init__:', type(self))
    >>>         print('Args in __init__:', args)
    
    6 trong đó việc “quên” dữ liệu được ánh xạ bộ nhớ không thể dẫn đến kết quả sai. Một ví dụ về lớp con đôi khi khiến người dùng nhầm lẫn là các mảng được che dấu của NumPy. Khi chúng được giới thiệu, phân lớp là cách tiếp cận duy nhất để thực hiện. Tuy nhiên, ngày nay chúng ta có thể cố gắng tránh phân lớp và chỉ dựa vào các giao thức tương tác

Lưu ý rằng các tác giả phân lớp cũng có thể muốn nghiên cứu để hỗ trợ các trường hợp sử dụng phức tạp hơn hoặc giải quyết hành vi đáng ngạc nhiên

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
7 và
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
8 là những ví dụ cho các đối tượng dạng mảng tương tác tốt với NumPy. Astropy's
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
9 là một ví dụ sử dụng cách tiếp cận kép của cả giao thức phân lớp và khả năng tương tác

Xem đúc

Truyền dạng xem là cơ chế ndarray tiêu chuẩn theo đó bạn lấy một ndarray của bất kỳ lớp con nào và trả về dạng xem của mảng dưới dạng một lớp con (được chỉ định) khác

>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

Tạo mới từ mẫu

Các phiên bản mới của một lớp con ndarray cũng có thể xuất hiện theo một cơ chế rất giống với , khi numpy nhận thấy nó cần tạo một phiên bản mới từ một phiên bản mẫu. Vị trí rõ ràng nhất mà điều này phải xảy ra là khi bạn đang lấy các mảng được phân lớp. Ví dụ

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False

Slice là một chế độ xem trên dữ liệu gốc của

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
0. Vì vậy, khi chúng tôi xem từ ndarray, chúng tôi trả về một ndarray mới, cùng loại, trỏ đến dữ liệu trong bản gốc

Có những điểm khác trong việc sử dụng ndarrays mà chúng ta cần các chế độ xem như vậy, chẳng hạn như sao chép mảng (

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
1), tạo mảng đầu ra ufunc (xem thêm) và các phương thức rút gọn (như
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
2)

Mối quan hệ của truyền dạng xem và mẫu mới từ mẫu

Cả hai con đường này đều sử dụng cùng một máy móc. Chúng tôi tạo ra sự khác biệt ở đây, bởi vì chúng dẫn đến đầu vào khác nhau cho các phương pháp của bạn. Cụ thể, có nghĩa là bạn đã tạo một thể hiện mới của kiểu mảng của mình từ bất kỳ lớp con tiềm năng nào của ndarray. có nghĩa là bạn đã tạo một thể hiện mới của lớp của mình từ một thể hiện có sẵn, cho phép bạn - ví dụ - sao chép qua các thuộc tính dành riêng cho lớp con của bạn

Ý nghĩa đối với phân lớp

Nếu chúng ta phân lớp ndarray, chúng ta không chỉ cần giải quyết việc xây dựng rõ ràng kiểu mảng của chúng ta, mà còn hoặc. NumPy có máy móc để làm điều này và chính máy móc này làm cho việc phân lớp con hơi phi tiêu chuẩn

Có hai khía cạnh đối với bộ máy mà ndarray sử dụng để hỗ trợ chế độ xem và mẫu mới từ mẫu trong các lớp con

Đầu tiên là việc sử dụng phương thức ________ 73 cho công việc chính là khởi tạo đối tượng, sau đó là phương thức ________ 74 thông thường hơn. Thứ hai là việc sử dụng phương thức

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 để cho phép các lớp con dọn dẹp sau khi tạo các khung nhìn và các thể hiện mới từ các mẫu

Sơ lược về Python ngắn gọn về >>> c = C('hello') Cls in __new__: Args in __new__: ('hello',) type(self) in __init__: Args in __init__: ('hello',) 6 và >>> c = C('hello') Cls in __new__: Args in __new__: ('hello',) type(self) in __init__: Args in __init__: ('hello',) 4

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 là một phương thức Python tiêu chuẩn, và nếu có, thì được gọi trước
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4 khi chúng ta tạo một thể hiện của lớp. Xem để biết thêm chi tiết

Ví dụ: hãy xem xét mã Python sau

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)

có nghĩa là chúng ta nhận được

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)

Khi chúng ta gọi

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
90, phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 lấy lớp riêng của nó làm đối số đầu tiên và đối số được truyền, đó là chuỗi
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
92. Sau khi python gọi
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6, nó thường (xem bên dưới) gọi phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4 của chúng ta, với đầu ra là ______76 làm đối số đầu tiên (hiện là phiên bản lớp) và các đối số được truyền theo sau

Như bạn có thể thấy, đối tượng có thể được khởi tạo trong phương thức

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 hoặc phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4 hoặc cả hai, và trên thực tế, ndarray không có phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4, bởi vì tất cả việc khởi tạo được thực hiện trong phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6

Tại sao lại sử dụng ________ 76 thay vì chỉ ________ 74 thông thường? . Hãy xem xét những điều sau đây

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
9

điều đó có nghĩa là

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
2

Định nghĩa của

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22 giống như trước, nhưng đối với
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
23, phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 trả về một thể hiện của lớp
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22 thay vì
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
23. Lưu ý rằng phương pháp
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4 của
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
23 không được gọi. Nói chung, khi phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 trả về một đối tượng của lớp khác với lớp mà nó được định nghĩa, thì phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
4 của lớp đó không được gọi

Đây là cách các lớp con của lớp ndarray có thể trả về các khung nhìn bảo toàn loại lớp. Khi xem, máy móc ndarray tiêu chuẩn tạo ra đối tượng ndarray mới với nội dung như

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
2

trong đó

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
21 là phân lớp. Do đó, chế độ xem được trả về thuộc cùng một lớp với lớp con, thay vì thuộc lớp
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22

Điều đó giải quyết vấn đề trả lại các lượt xem cùng loại, nhưng bây giờ chúng tôi có một vấn đề mới. Bộ máy của ndarray có thể thiết lập lớp theo cách này, trong các phương thức tiêu chuẩn của nó để lấy các khung nhìn, nhưng phương thức

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 của ndarray không biết gì về những gì chúng ta đã làm trong phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 của riêng mình để thiết lập các thuộc tính, v.v. (Bên cạnh đó - tại sao không gọi
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
25? Bởi vì chúng tôi có thể không có phương thức
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
6 có cùng chữ ký cuộc gọi)

Vai trò của >>> c = C('hello') Cls in __new__: Args in __new__: ('hello',) type(self) in __init__: Args in __init__: ('hello',) 5

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 là cơ chế mà numpy cung cấp để cho phép các lớp con xử lý các cách khác nhau mà các phiên bản mới được tạo

Hãy nhớ rằng các thể hiện của lớp con có thể xảy ra theo ba cách sau

  1. cuộc gọi hàm tạo rõ ràng (

    >>> class C:
    >>>     def __new__(cls, *args):
    >>>         print('Cls in __new__:', cls)
    >>>         print('Args in __new__:', args)
    >>>         # The `object` type __new__ method takes a single argument.
    >>>         return object.__new__(cls)
    >>>     def __init__(self, *args):
    >>>         print('type(self) in __init__:', type(self))
    >>>         print('Args in __init__:', args)
    
    29). Điều này sẽ gọi chuỗi thông thường của
    >>> import numpy as np
    >>> # create a completely useless ndarray subclass
    >>> class C(np.ndarray): pass
    >>> # create a standard ndarray
    >>> arr = np.zeros((3,))
    >>> # take a view of it, as our useless subclass
    >>> c_arr = arr.view(C)
    >>> type(c_arr)
    
    
    20 sau đó (nếu nó tồn tại)
    >>> import numpy as np
    >>> # create a completely useless ndarray subclass
    >>> class C(np.ndarray): pass
    >>> # create a standard ndarray
    >>> arr = np.zeros((3,))
    >>> # take a view of it, as our useless subclass
    >>> c_arr = arr.view(C)
    >>> type(c_arr)
    
    
    21

Phương thức

>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

20 của chúng tôi chỉ được gọi trong trường hợp lệnh gọi hàm tạo rõ ràng, vì vậy chúng tôi không thể dựa vào
>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

20 hoặc
>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

21 để xử lý việc truyền khung nhìn và tạo mẫu mới. Nó chỉ ra rằng
>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

25 được gọi cho cả ba phương thức tạo đối tượng, vì vậy đây là nơi mà công việc dọn dẹp tạo đối tượng của chúng ta thường thực hiện

  • Đối với lệnh gọi hàm tạo rõ ràng, lớp con của chúng ta sẽ cần tạo một thể hiện ndarray mới của lớp riêng của nó. Trong thực tế, điều này có nghĩa là chúng tôi, tác giả của mã, sẽ cần thực hiện cuộc gọi tới

    >>> import numpy as np
    >>> # create a completely useless ndarray subclass
    >>> class C(np.ndarray): pass
    >>> # create a standard ndarray
    >>> arr = np.zeros((3,))
    >>> # take a view of it, as our useless subclass
    >>> c_arr = arr.view(C)
    >>> type(c_arr)
    
    
    26, một cuộc gọi được chuẩn bị theo hệ thống phân cấp lớp tới
    >>> import numpy as np
    >>> # create a completely useless ndarray subclass
    >>> class C(np.ndarray): pass
    >>> # create a standard ndarray
    >>> arr = np.zeros((3,))
    >>> # take a view of it, as our useless subclass
    >>> c_arr = arr.view(C)
    >>> type(c_arr)
    
    
    27 hoặc xem việc truyền một mảng hiện có (xem bên dưới)

  • Đối với chế độ xem và tính năng mới từ mẫu, tương đương với

    >>> import numpy as np
    >>> # create a completely useless ndarray subclass
    >>> class C(np.ndarray): pass
    >>> # create a standard ndarray
    >>> arr = np.zeros((3,))
    >>> # take a view of it, as our useless subclass
    >>> c_arr = arr.view(C)
    >>> type(c_arr)
    
    
    28 được gọi, ở cấp độ C

Các đối số mà

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 nhận được khác nhau đối với ba phương pháp tạo cá thể ở trên

Đoạn mã sau cho phép chúng ta xem xét các chuỗi cuộc gọi và đối số

>>> import numpy as np
>>> # create a completely useless ndarray subclass
>>> class C(np.ndarray): pass
>>> # create a standard ndarray
>>> arr = np.zeros((3,))
>>> # take a view of it, as our useless subclass
>>> c_arr = arr.view(C)
>>> type(c_arr)

2

Bây giờ

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
3

Chữ ký của

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 là

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
5

Người ta thấy rằng cuộc gọi

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31, đi đến
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
3, chuyển
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 đối tượng mới, thuộc lớp của chính chúng ta (
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
34) cũng như đối tượng mà chế độ xem đã được thực hiện (
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
35). Như bạn có thể thấy từ đầu ra ở trên,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
34 luôn là một phiên bản mới được tạo của lớp con của chúng tôi và loại
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
35 khác nhau đối với ba phương thức tạo phiên bản

  • Khi được gọi từ hàm tạo rõ ràng,

    >>> v = c_arr[1:]
    >>> type(v) # the view is of type 'C'
    
    >>> v is c_arr # but it's a new instance
    False
    
    35 là
    >>> v = c_arr[1:]
    >>> type(v) # the view is of type 'C'
    
    >>> v is c_arr # but it's a new instance
    False
    
    39

  • Khi được gọi từ chế độ xem,

    >>> v = c_arr[1:]
    >>> type(v) # the view is of type 'C'
    
    >>> v is c_arr # but it's a new instance
    False
    
    35 có thể là một thể hiện của bất kỳ lớp con nào của ndarray, bao gồm cả lớp con của chúng ta

  • Khi được gọi trong mẫu mới,

    >>> v = c_arr[1:]
    >>> type(v) # the view is of type 'C'
    
    >>> v is c_arr # but it's a new instance
    False
    
    35 là một phiên bản khác của lớp con của chúng tôi, mà chúng tôi có thể sử dụng để cập nhật phiên bản
    >>> v = c_arr[1:]
    >>> type(v) # the view is of type 'C'
    
    >>> v is c_arr # but it's a new instance
    False
    
    34 mới

Bởi vì

>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 là phương thức duy nhất luôn thấy các phiên bản mới được tạo, nên đây là nơi hợp lý để điền vào các giá trị mặc định của phiên bản cho các thuộc tính đối tượng mới, trong số các tác vụ khác

Điều này có thể rõ ràng hơn với một ví dụ

Ví dụ đơn giản - thêm thuộc tính bổ sung vào ndarray

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
0

Sử dụng đối tượng trông như thế này

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
1

Lớp này không hữu ích lắm, bởi vì nó có cùng hàm tạo như đối tượng ndarray trần, bao gồm cả việc truyền vào bộ đệm và hình dạng, v.v. Chúng tôi có thể muốn hàm tạo có thể lấy một ndarray đã được tạo sẵn từ các lệnh gọi numpy thông thường tới

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
54 và trả về một đối tượng

Ví dụ thực tế hơn một chút - thuộc tính được thêm vào mảng hiện có

Đây là một lớp lấy một ndarray tiêu chuẩn đã tồn tại, chuyển thành kiểu của chúng tôi và thêm một thuộc tính bổ sung

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
2

Vì thế

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
3

>>> v = c_arr[1:] >>> type(v) # the view is of type 'C' >>> v is c_arr # but it's a new instance False 55 cho ufunc

Mới trong phiên bản 1. 13

Một lớp con có thể ghi đè những gì xảy ra khi thực thi ufuncs numpy trên nó bằng cách ghi đè phương thức

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
56 mặc định. Phương thức này được thực thi thay vì ufunc và sẽ trả về kết quả của thao tác hoặc nếu thao tác được yêu cầu không được thực hiện

Chữ ký của

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55 là

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
4

Một triển khai điển hình sẽ chuyển đổi bất kỳ đầu vào hoặc đầu ra nào là thể hiện của một lớp riêng, chuyển mọi thứ sang lớp cha bằng cách sử dụng

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
59 và cuối cùng trả về kết quả sau khi có thể chuyển đổi ngược. Một ví dụ, được lấy từ test case
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
00 trong
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
01, như sau

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
5

Vì vậy, lớp học này không thực sự làm bất cứ điều gì thú vị. nó chỉ chuyển đổi bất kỳ phiên bản nào của chính nó thành ndarray thông thường (nếu không, chúng ta sẽ nhận được đệ quy vô hạn. ) và thêm một từ điển

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
02 cho biết nó đã chuyển đổi đầu vào và đầu ra nào. Do đó, đ. g. ,

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
6

Lưu ý rằng một cách tiếp cận khác sẽ là sử dụng

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
03 thay vì cuộc gọi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31. Đối với ví dụ này, kết quả sẽ giống hệt nhau, nhưng sẽ có sự khác biệt nếu một toán hạng khác cũng xác định
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55. e. g. , giả sử rằng chúng ta đánh giá ________ 606, trong đó _________ 607 là một thể hiện của một lớp khác
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
08 có quyền ghi đè. Nếu bạn sử dụng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 như trong ví dụ, thì
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
56 sẽ nhận thấy rằng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
07 có giá trị ghi đè, nghĩa là nó không thể tự đánh giá kết quả. Do đó, nó sẽ trả về NotImplemented và lớp
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
12 của chúng ta cũng vậy. Sau đó, quyền kiểm soát sẽ được chuyển cho
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
07, biết cách xử lý chúng ta và đưa ra kết quả, hoặc không biết và trả về NotImplemented, làm tăng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
14

Nếu thay vào đó, chúng tôi thay thế cuộc gọi

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 của mình bằng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
16, chúng tôi thực sự thực hiện
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
17. Một lần nữa,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
18 sẽ được gọi, nhưng bây giờ nó xem một đối số khác là
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22. Có khả năng, nó sẽ biết cách xử lý việc này và trả về một phiên bản mới của lớp
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
08 cho chúng tôi. Lớp ví dụ của chúng tôi không được thiết lập để xử lý việc này, nhưng nó có thể là cách tiếp cận tốt nhất nếu, e. g. , một là triển khai lại
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
21 bằng cách sử dụng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55

Như một lưu ý cuối cùng. nếu tuyến đường

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 phù hợp với một lớp nhất định, một lợi thế của việc sử dụng nó là nó giúp xây dựng hệ thống phân cấp lớp. e. g. , giả sử rằng lớp khác của chúng tôi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
08 cũng đã sử dụng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 trong triển khai
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55 của nó và chúng tôi đã tạo một lớp
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22 phụ thuộc vào cả hai, tôi. e. ,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
28 (với, để đơn giản, không phải ghi đè
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55 khác). Sau đó, bất kỳ ufunc nào trên phiên bản của
>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22 sẽ chuyển sang
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31, lệnh gọi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 trong
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
12 sẽ chuyển đến
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
18 và lệnh gọi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
31 trong
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
08 sẽ chuyển đến
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
56, do đó cho phép
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
12 và
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
08 cộng tác

>>> v = c_arr[1:] >>> type(v) # the view is of type 'C' >>> v is c_arr # but it's a new instance False 40 cho ufunc và các chức năng khác

Trước numpy 1. 13, hành vi của ufunc chỉ có thể được điều chỉnh bằng cách sử dụng

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 và
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
42. Hai thứ này cho phép một người thay đổi loại đầu ra của ufunc, nhưng ngược lại với
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
55, không cho phép một người thực hiện bất kỳ thay đổi nào đối với đầu vào. Người ta hy vọng cuối cùng sẽ không dùng những thứ này nữa, nhưng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 cũng được sử dụng bởi các hàm và phương thức numpy khác, chẳng hạn như
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
45, vì vậy tại thời điểm hiện tại vẫn cần thiết cho chức năng đầy đủ

Về mặt khái niệm,

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 “kết thúc hành động” theo nghĩa cho phép một lớp con đặt loại giá trị trả về và cập nhật các thuộc tính và siêu dữ liệu. Hãy chỉ ra cách thức hoạt động của nó với một ví dụ. Đầu tiên, chúng ta trở lại lớp con ví dụ đơn giản hơn, nhưng với một tên khác và một số câu lệnh in

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
7

Chúng tôi chạy một ufunc trên một phiên bản của mảng mới của chúng tôi

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
8

Lưu ý rằng ufunc (

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
47) đã gọi phương thức
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 với các đối số
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
34 là
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
35 và
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
51 là kết quả (ndarray) của phép cộng. Đổi lại, mặc định
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 (
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
53) đã chuyển kết quả sang lớp
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
54 và được gọi là
>>> c = C('hello')
Cls in __new__: 
Args in __new__: ('hello',)
type(self) in __init__: 
Args in __init__: ('hello',)
5 - do đó sao chép thuộc tính
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
02. Điều này đã xảy ra ở cấp độ C

Nhưng, chúng tôi có thể làm bất cứ điều gì chúng tôi muốn

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
9

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
0

Vì vậy, bằng cách định nghĩa một phương thức

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 cụ thể cho lớp con của chúng ta, chúng ta có thể điều chỉnh đầu ra từ ufuncs. Phương thức
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 yêu cầu
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
34, sau đó là đối số - là kết quả của ufunc - và bối cảnh tham số tùy chọn. Tham số này được ufuncs trả về dưới dạng bộ 3 phần tử. (tên của ufunc, đối số của ufunc, tên miền của ufunc), nhưng không được đặt bởi các hàm numpy khác. Mặc dù, như đã thấy ở trên, có thể làm khác đi, nhưng
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40 sẽ trả về một thể hiện của lớp chứa nó. Xem phân lớp mảng bị che để triển khai

Ngoài

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40, được gọi trên đường ra khỏi ufunc, còn có một phương thức
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
42 được gọi trên đường vào ufunc, sau khi các mảng đầu ra được tạo nhưng trước khi bất kỳ phép tính nào được thực hiện. Việc triển khai mặc định không làm gì ngoài việc chuyển qua mảng.
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
42 không nên cố gắng truy cập dữ liệu mảng hoặc thay đổi kích thước mảng, nó được dùng để đặt loại mảng đầu ra, cập nhật thuộc tính và siêu dữ liệu và thực hiện bất kỳ kiểm tra nào dựa trên đầu vào có thể được mong muốn trước khi bắt đầu tính toán. Giống như
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
40,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
42 phải trả về ndarray hoặc lớp con của chúng hoặc đưa ra lỗi

Gotchas bổ sung - phương pháp >>> v = c_arr[1:] >>> type(v) # the view is of type 'C' >>> v is c_arr # but it's a new instance False 66 tùy chỉnh và ndarray. cơ sở

Một trong những vấn đề mà ndarray giải quyết là theo dõi quyền sở hữu bộ nhớ của ndarray và quan điểm của chúng. Xem xét trường hợp chúng tôi đã tạo một ndarray,

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
67 và đã cắt một lát với
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
68. Hai đối tượng đang nhìn vào cùng một bộ nhớ. NumPy theo dõi dữ liệu đến từ đâu cho một mảng hoặc chế độ xem cụ thể, với thuộc tính
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
69

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
1

Nói chung, nếu mảng sở hữu bộ nhớ riêng của nó, như đối với

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
67 trong trường hợp này, thì
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
71 sẽ là Không có - có một số trường hợp ngoại lệ đối với điều này - xem sách numpy để biết thêm chi tiết

Thuộc tính

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
69 rất hữu ích trong việc có thể cho biết liệu chúng ta có chế độ xem hay mảng ban đầu. Đến lượt nó, điều này có thể hữu ích nếu chúng ta cần biết có nên thực hiện một số thao tác dọn dẹp cụ thể hay không khi mảng phân lớp bị xóa. Ví dụ: chúng tôi có thể chỉ muốn thực hiện dọn dẹp nếu mảng ban đầu bị xóa chứ không phải chế độ xem. Để biết ví dụ về cách thức hoạt động của tính năng này, hãy xem lớp
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
73 trong
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
74

Phân lớp và khả năng tương thích xuôi dòng

Khi phân lớp phụ ________ 422 hoặc tạo các loại vịt bắt chước giao diện ________ 422, bạn có trách nhiệm quyết định mức độ liên kết giữa các API của mình với các API của numpy. Để thuận tiện, nhiều hàm numpy có phương thức

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
22 tương ứng (e. g. ,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
78,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
79,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
80,
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
81) hoạt động bằng cách kiểm tra xem đối số đầu tiên của hàm có phương thức cùng tên hay không. Nếu nó tồn tại, phương thức được gọi thay vì ép buộc các đối số thành một mảng có nhiều mảng

Ví dụ: nếu bạn muốn lớp con hoặc loại vịt của mình tương thích với hàm ________ 678 của numpy, chữ ký phương thức cho phương thức ________ 678 của đối tượng này phải như sau

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
2

Đây chính xác là chữ ký phương thức tương tự cho

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
84, vì vậy bây giờ nếu người dùng gọi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
84 trên đối tượng này, numpy sẽ gọi phương thức
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
78 của chính đối tượng và chuyển các đối số được liệt kê ở trên vào chữ ký và sẽ không có lỗi nào xảy ra vì chữ ký là

Tuy nhiên, nếu bạn quyết định đi chệch khỏi chữ ký này và làm điều gì đó như thế này

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
3

Đối tượng này không còn tương thích với

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
84 vì nếu bạn gọi
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
84, nó sẽ truyền vào các đối số không mong muốn là
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
89 và
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
90, gây ra TypeError

Nếu bạn muốn duy trì khả năng tương thích với numpy và các phiên bản tiếp theo của nó (có thể thêm các đối số từ khóa mới) nhưng không muốn hiển thị tất cả các đối số của numpy, thì chữ ký của hàm của bạn phải chấp nhận

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
91. Ví dụ

>>> class C:
>>>     def __new__(cls, *args):
>>>         print('Cls in __new__:', cls)
>>>         print('Args in __new__:', args)
>>>         # The `object` type __new__ method takes a single argument.
>>>         return object.__new__(cls)
>>>     def __init__(self, *args):
>>>         print('type(self) in __init__:', type(self))
>>>         print('Args in __init__:', args)
4

Đối tượng này hiện tương thích lại với

>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
84 vì bất kỳ đối số không liên quan nào (i. e. các từ khóa không phải là
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
93 hoặc
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
94) sẽ bị ẩn đi trong tham số
>>> v = c_arr[1:]
>>> type(v) # the view is of type 'C'

>>> v is c_arr # but it's a new instance
False
95

Một lớp có thể trả lại thứ gì đó Python không?

Vì mọi thứ trong Python đều là đối tượng nên bạn có thể trả về chuỗi, danh sách, bộ dữ liệu, từ điển, hàm, lớp, thể hiện, đối tượng do người dùng định nghĩa và thậm chí cả mô-đun hoặc gói< . .

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

Mảng có thể được tạo bằng Python bằng cách nhập mô-đun mảng vào chương trình python. .
từ nhập mảng *
arrayName = array(typecode, [initializers])

Làm cách nào để đọc mảng trong Python?

Làm cách nào để nhập mảng trong python? .
a=int(input("Số phần tử của mảng. -"))
n=list(map(int, input("các phần tử của mảng. -"). dải(). tách ra()))
in(n)

Làm cách nào để nối thêm mảng trong Python?

Nếu bạn đang sử dụng Danh sách dưới dạng một mảng, bạn có thể sử dụng các hàm append(), insert() và expand() của nó. .
Nếu bạn đang sử dụng mô-đun mảng, bạn có thể sử dụng phép nối bằng toán tử +, các hàm append(), insert() và expand() để thêm các phần tử vào mảng