How do you filter a class object in python?

The OP wants to do this MyData.objects.filter[id>1].

Let's face it.

The problem is Python is greedy [eagerly evaluates expressions], not lazy like Haskell.
Watch David Beazley - Lambda Calculus from the Ground Up - PyCon 2019 for mind-bending λ thing.

Python evaluates id > 1 before calling filter. If we can stop the evaluation for now, we can pass the expression unevaluated to the filter function.

But we can delay expression evaluation until required if we enclose the expression in a function. That's the idea.

The function interface would be filter[lambda: id > 1] if we could implement it. This interface will be super versatile because any Python expression can be passed and abused.

The implementation;

if we invoke the lambda or any other function with the expression id > 1, Python looks up the name id in the local, enclosing, global scope or builtins depending on the context where the function is invoked.

If we can introduce an object with the name id somewhere in the look-up path before Python finds id in the builtins we can redefine the semantics of the expression.

I'm gonna do it with eval which evaluates expressions in the given context.

DATA = [
    {'id': 1, 'name': 'brad', 'color':'red'},
    {'id': 2, 'name': 'sylvia', 'color':'blue'},
]

def myfilter[a_lambda]:
    return filter[lambda obj: eval[a_lambda.__code__, obj.copy[]],
    DATA]

I pass a dict.copy to eval because eval modifies it's globals object.

See it in action in the context of Model class

In [1]: class Data[Model]:
   ...:     name = str[]
   ...:     id = int[]
   ...:     color = str[]
   ...: 

In [2]: Data.objects.create[**{"id": 1, "name": "brad", "color": "red"}]

In [3]:     Data.objects.create[**{"id": 2, "name": "sylvia", "color": "blue"}]

In [4]:     Data.objects.create[**{"id": 3, "name": "paul", "color": "red"}]

In [5]:     Data.objects.create[**{"id": 4, "name": "brandon", "color": "yello"}]

In [6]:     Data.objects.create[**{"id": 5, "name": "martin", "color": "green"}]

In [7]:     Data.objects.create[**{"id": 6, "name": "annie", "color": "gray"}]

In [8]: pprint[[vars[obj] for obj in Data.objects.filter[lambda: id == 1]]]
[{'color': 'red', 'id': 1, 'name': 'brad'}]

In [9]: pprint[[vars[obj] for obj in Data.objects.filter[lambda: 1 

Chủ Đề