1
\$\begingroup\$

In some of my peewee-based ORM models, I need to access the instance as well as the respective class. Since I caught myself always repeating the line cls = self.__class__ at the top of each such methods, I wrote a decorator for that:

def with_class(function):
 """Adds the instance's class as second
 parameter to the wrapped function.
 """
 @wraps(function)
 def wrapper(self, *args, **kwargs):
 """Wraps the given function."""
 return function(self, self.__class__, *args, **kwargs)
 return wrapper

Example use case:

class Location(_TerminalModel):
 """Location of a terminal."""
 address = CascadingFKField(Address, column_name='address')
 annotation = CharField(255, null=True)
 ...
 @with_class
 def save_unique(self, cls, *args, **kwargs):
 """Saves the location if it is new or
 returns the appropriate existing record.
 """
 if self.annotation is None:
 annotation_selector = cls.annotation >> None
 else:
 annotation_selector = cls.annotation == self.annotation
 try:
 return cls.get((cls.address == self.address) & annotation_selector)
 except cls.DoesNotExist:
 self.save(*args, **kwargs)
 return self

I'd like to have critique on this solution and am open to alternatives.

asked Jul 23, 2018 at 12:59
\$\endgroup\$
2
  • 3
    \$\begingroup\$ So, you saved typing a single line at the expense of typing a single line? :-\ \$\endgroup\$ Commented Jul 23, 2018 at 13:19
  • \$\begingroup\$ @bipll Good point. \$\endgroup\$ Commented Jul 23, 2018 at 13:26

1 Answer 1

3
\$\begingroup\$

I'd recommend not using value.__class__. This is as it's not guaranteed to return the type.

type(x) is typically the same as x.__class__ (although this is not guaranteed – a new-style class instance is permitted to override the value returned for x.__class__).

Take:

class A:
 __class__ = 'something'
print(A.__class__) # <class 'type'>
print(A().__class__) # 'something'
print(type(A())) # <class '__main__.A'>

I also think just using type would be cleaner, and easier to understand.

def save_unique(self, *args, **kwargs):
 cls = type(self)
answered Jul 23, 2018 at 14:02
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.