In skrub, DataOp objects represent computations that have not been executed yet. They are only triggered when you call .skb.eval() or when you create a pipeline using .skb.make_learner() and call methods like fit().
Because DataOp objects are lazy, you cannot use standard Python control flow (like if, for, or with) directly on them. For example, attempting to iterate over orders.columns will fail because orders.columns is itself a DataOp that will produce a list of columns only when evaluated, not a literal list available immediately.
To use Python control flow, you must wrap the logic in a function that is executed only when the data is actually available.
>>> import pandas as pd
>>> import skrub
>>> orders_df = pd.DataFrame({"item": ["pen", "cup"], "price": [1.5, None], "qty": [1, 1]})
>>> orders = skrub.var("orders", orders_df)
>>> for column in orders.columns:
... pass
TypeError: This object is a DataOp that will be evaluated later...