I have a method on one of my objects that returns a new instance of that same class. I’m trying to figure out the most idiomatic way to write this method such that it generates a new object of the same type without duplicating code.
Since this method uses data from the instance, my first pass is:
class Foo(object):
def get_new(self):
data = # Do interesting things
return Foo(data)
However, if I subclass Foo and don’t override get_new, calling get_new on SubFoo would return a Foo! So, I could write a classmethod:
class Foo(object):
@classmethod
def get_new(cls, obj):
data = # Munge about in objects internals
return cls(data)
However, the data I’m accessing is specific to the object, so it seems to break encapsulation for this not to be a “normal” (undecorated) method. Additionally, you then have to call it like SubFoo.get_new(sub_foo_inst), which seems redundant. I’d like the object to just “know” which type to return — the same type as itself!
I suppose it’s also possible to add a factory method to the class, and override the return type everywhere, without duplicating the logic, but that seems to put a lot of work on the subclasses.
So, my question is, what’s the best way to write a method that gives flexibility in type of class without having to annotate the type all over the place?
If you want to make it more flexible for subclassing, you can simply use the
self.__class__special attribute:Note that using the
@classmethodapproach will prevent you from accessing data within any one instance, removing it as a viable solution in instances where#Do interesting thingsrelies on data stored within an instance.For Python 2, I do not recommend using
type(self), as this will return an inappropriate value for classic classes (i.e., those not subclassed from the baseobject):For Python 3, this is not as much of an issue, as all classes are derived from
object, however, I believeself.__class__is considered the more Pythonic idiom.