Skip to content

Instantly share code, notes, and snippets.

@malexer
Last active November 2, 2016 09:10
Show Gist options
  • Save malexer/2593c2e945e94c2f3d4f54212cbbc010 to your computer and use it in GitHub Desktop.
Save malexer/2593c2e945e94c2f3d4f54212cbbc010 to your computer and use it in GitHub Desktop.
Trying to reimplement SQLAlchemy's query.filter magic
# after using SQLAlchemy I've decided to try my python skills in coding it's filter function magic
# without looking into their source code, just for fun
# Note: it's not complete, just proof of concept
class BindProperty(type):
def __new__(cls, name, bases, namespace, **kwds):
result = type.__new__(cls, name, bases, dict(namespace))
for name, value in namespace.items():
if isinstance(value, Property):
value._update_attribute_name(name)
return result
class Condition(object):
def __init__(self, property_name):
self.property_name = property_name
def __gt__(self, other):
return lambda instance: getattr(instance, self.property_name) > other
def __eq__(self, other):
return lambda instance: getattr(instance, self.property_name) == other
class Property(object):
def _update_attribute_name(self, property_name):
self.instance_attribute_name = '_%s' % property_name
self.condition_checker = Condition(property_name)
def __get__(self, instance, owner):
if instance is None:
return self.condition_checker
else:
return getattr(instance, self.instance_attribute_name, None)
def __set__(self, instance, value):
setattr(instance, self.instance_attribute_name, value)
class User(object, metaclass=BindProperty):
name = Property()
age = Property()
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return '<User(name="%s", age=%s)>' % (self.name, self.age)
def where(items, *conditions):
return [
item for item in items
if all([c(item) for c in conditions])
]
users = (
User('Alex', 19),
User('John', 21),
User('Mark', 25),
User('John', 15),
)
print('Source:', users)
filtered1 = where(users, User.name == 'John')
print('filtered1:', filtered1)
filtered2 = where(users, User.age > 18)
print('filtered2:', filtered2)
filtered3 = where(users, User.name == 'John', User.age > 20)
print('filtered3:', filtered3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment