Bird
Raised Fist0
NumPydata~10 mins

Array protocol and __array__ in NumPy - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Array protocol and __array__
Object with __array__ method
↓
Call np.array(obj)
↓
Check if obj has __array__
↓
Call obj.__array__()
↓
Get numpy array
↓
Use numpy array for computations
When numpy.array() is called on an object, it checks if the object has a __array__ method. If yes, it calls this method to get a numpy array representation. Otherwise, it converts the object by default.
Execution Sample
NumPy
import numpy as np
class MyData:
    def __array__(self):
        return np.array([1, 2, 3])
obj = MyData()
arr = np.array(obj)
This code creates a class with __array__ method that returns a numpy array. When np.array() is called on an instance, it uses __array__ to get the array.
Execution Table
StepActionCheck __array__Call __array__()Resulting ArrayNotes
1Create instance obj of MyDataN/AN/AN/Aobj is a custom object
2Call np.array(obj)Yes, obj has __array__Called obj.__array__()array([1, 2, 3])np.array uses __array__ method
3np.array returns the arrayN/AN/Aarray([1, 2, 3])Array ready for use
4Use arr in computationsN/AN/Aarray([1, 2, 3])Standard numpy array behavior
5EndN/AN/AN/AProcess complete
💡 np.array() finishes after calling __array__ and obtaining the numpy array
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
objNoneMyData instanceMyData instanceMyData instanceMyData instance
arrNoneNonearray([1, 2, 3])array([1, 2, 3])array([1, 2, 3])
Key Moments - 3 Insights
Why does np.array(obj) call obj.__array__() instead of converting obj directly?
Because numpy checks if the object has a __array__ method to get a direct numpy array representation, which is more efficient and accurate. See execution_table step 2.
What happens if the object does not have a __array__ method?
Numpy tries to convert the object by default methods like iterating or using buffer protocols. This is shown in the concept_flow where the 'No' branch leads to default conversion.
Can __array__ return any type of array?
Yes, __array__ should return a numpy ndarray or something convertible to it. Returning other types may cause errors or unexpected behavior.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2, what does np.array(obj) do?
AConverts obj by default without calling __array__
BCalls obj.__array__() to get a numpy array
CRaises an error because obj is not an array
DReturns obj unchanged
💡 Hint
Check the 'Check __array__' and 'Call __array__()' columns at step 2 in execution_table
According to variable_tracker, what is the value of arr after step 3?
Aarray([1, 2, 3])
BNone
CMyData instance
DAn error
💡 Hint
Look at the 'arr' row and 'After Step 3' column in variable_tracker
If MyData.__array__ returned array([4,5,6]) instead, what would arr be after step 3?
AMyData instance
Barray([1, 2, 3])
Carray([4, 5, 6])
DNone
💡 Hint
The __array__ method defines the array returned by np.array(obj), see execution_table step 2
Concept Snapshot
Array protocol (__array__) lets objects define how to convert themselves to numpy arrays.
When np.array(obj) is called, numpy checks for __array__ method.
If found, it calls obj.__array__() to get the array.
This allows custom objects to integrate smoothly with numpy.
If no __array__, numpy uses default conversion methods.
Full Transcript
This visual execution trace shows how numpy's array protocol works with the __array__ method. When np.array() is called on an object, numpy checks if the object has a __array__ method. If yes, it calls this method to get a numpy array representation. Otherwise, it converts the object by default. The example code defines a class MyData with __array__ returning array([1, 2, 3]). When np.array(obj) is called, it calls obj.__array__() and returns the numpy array. The execution table traces each step: creating the object, calling np.array, checking for __array__, calling it, and returning the array. The variable tracker shows how variables obj and arr change during execution. Key moments clarify why __array__ is used and what happens if it is missing. The quiz questions test understanding of these steps. The concept snapshot summarizes the array protocol as a way for objects to define their numpy array conversion. This helps beginners see the step-by-step process and understand how numpy integrates with custom objects.

Practice

(1/5)
1. What is the main purpose of the __array__ method in a custom Python class when working with NumPy?
easy
A. To create a plot from the array data
B. To allow the object to be converted automatically into a NumPy array
C. To perform element-wise multiplication on arrays
D. To define a new data type for NumPy arrays

Solution

  1. Step 1: Understand the role of __array__

    The __array__ method is designed to let custom objects tell NumPy how to convert them into arrays.
  2. Step 2: Identify the main purpose

    This method enables automatic conversion, so NumPy can work with the data efficiently.
  3. Final Answer:

    To allow the object to be converted automatically into a NumPy array -> Option B
  4. Quick Check:

    Conversion to NumPy array [OK]
Hint: Remember: __array__ means 'convert me to array' [OK]
Common Mistakes:
  • Confusing __array__ with data type definition
  • Thinking __array__ performs calculations
  • Assuming __array__ creates plots
2. Which of the following is the correct way to define the __array__ method in a custom class to return a NumPy array?
easy
A. def __array__(self, dtype): return self.data.astype(dtype)
B. def __array__(self): return list(self.data)
C. def __array__(self): return self.data.tolist()
D. def __array__(self, dtype=None): return np.array(self.data, dtype=dtype)

Solution

  1. Step 1: Check method signature

    The __array__ method should accept an optional dtype argument for flexibility.
  2. Step 2: Verify return type

    It must return a NumPy array, so using np.array(self.data, dtype=dtype) is correct.
  3. Final Answer:

    def __array__(self, dtype=None): return np.array(self.data, dtype=dtype) -> Option D
  4. Quick Check:

    Correct signature and return type [OK]
Hint: Include dtype=None and return np.array inside __array__ [OK]
Common Mistakes:
  • Omitting dtype parameter
  • Returning list instead of np.array
  • Using tolist() which returns Python list
3. Given the code below, what will be the output of print(np.array(obj))?
import numpy as np

class MyData:
    def __init__(self):
        self.data = [1, 2, 3]
    def __array__(self, dtype=None):
        return np.array(self.data, dtype=dtype)

obj = MyData()
print(np.array(obj))
medium
A. [1 2 3]
B. [[1 2 3]]
C. TypeError: object cannot be converted to array
D. [1, 2, 3]

Solution

  1. Step 1: Understand __array__ method behavior

    The method returns a NumPy array created from the list [1, 2, 3].
  2. Step 2: Predict np.array conversion

    Calling np.array(obj) triggers obj.__array__(), returning np.array([1, 2, 3]), which prints as [1 2 3].
  3. Final Answer:

    [1 2 3] -> Option A
  4. Quick Check:

    Custom __array__ returns array [1 2 3] [OK]
Hint: np.array calls __array__, returns array, prints without commas [OK]
Common Mistakes:
  • Expecting Python list output with commas
  • Thinking output is nested array
  • Assuming TypeError due to custom class
4. What is wrong with this __array__ method implementation?
def __array__(self):
    return self.data.astype(float)
medium
A. It does not accept the optional dtype argument
B. astype cannot convert to float
C. Returning self.data directly is required
D. The method should return a list, not an array

Solution

  1. Step 1: Check method signature

    The __array__ method should accept an optional dtype argument to allow flexible conversions.
  2. Step 2: Identify missing dtype parameter

    This method lacks the dtype=None parameter, so it cannot handle dtype requests from NumPy.
  3. Final Answer:

    It does not accept the optional dtype argument -> Option A
  4. Quick Check:

    Missing dtype parameter [OK]
Hint: Always include dtype=None in __array__ method [OK]
Common Mistakes:
  • Forgetting dtype argument
  • Thinking astype cannot convert types
  • Returning list instead of array
5. You have a custom class with a __array__ method that returns a NumPy array. You want to ensure that when you call np.array(obj, dtype=np.float64), the returned array respects the requested dtype. How should you modify the __array__ method?
hard
A. def __array__(self, dtype=None): return np.array(self.data)
B. def __array__(self): return np.array(self.data, dtype=np.float64)
C. def __array__(self, dtype=None): return np.array(self.data, dtype=dtype)
D. def __array__(self, dtype): return self.data.astype(dtype)

Solution

  1. Step 1: Understand dtype propagation

    NumPy passes the requested dtype to __array__ as an argument; the method must accept it.
  2. Step 2: Implement dtype-aware conversion

    Return np.array(self.data, dtype=dtype) so the requested dtype is applied correctly.
  3. Final Answer:

    def __array__(self, dtype=None): return np.array(self.data, dtype=dtype) -> Option C
  4. Quick Check:

    Accept dtype and pass to np.array [OK]
Hint: Pass dtype argument to np.array inside __array__ method [OK]
Common Mistakes:
  • Ignoring dtype argument
  • Hardcoding dtype inside method
  • Not accepting dtype parameter
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard