Skip to content

Instantly share code, notes, and snippets.

@devilholk
Last active March 19, 2017 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devilholk/3732e7c05264d489cf31349f036c556c to your computer and use it in GitHub Desktop.
Save devilholk/3732e7c05264d489cf31349f036c556c to your computer and use it in GitHub Desktop.
Example usage of the __new__ method of python objects
class list_of_lines:
__slots__ = 'data', #Not necersary for this example but __slots__ is always
# nice to make the members a bit more strictly defined
def __new__(cls, text_or_instance):
#We use cls instead of self to make it clear that it is the class,
# not the new instance as you would with __init__
#You could use __init__ together with __new__ of course but then you
# need to make sure the arguments of __init__ is compatible
# with the arguments of __new__
#We check if text_or_instance is an instance of cls.
#We could use the condition isinstance(text_or_instance, cls) but then
# if we put an instance of some_child_of_list_of_lines in
# text_or_instance it will fail when we try to use .split since
# we just assume it is a string if this condition fails.
#To allow for children to pass we can use the following condition that
# will allow text_or_instance to be an instance of a parent of cls
if issubclass(cls, text_or_instance.__class__):
return text_or_instance
#The above condition failed so we are assuming that text_or_instance
# is a str
#We use the __new__ function of object to create the instance and
# assign members, in this case just .data to the str split into
# a list by linebreak
result = object.__new__(cls)
result.data = text_or_instance.split('\n')
return result
#We define a function to represent this instance when used with repr()
# or %r in a formatted string
#This function adds the number of lines to the object.__repr__
# standard way
def __repr__(self):
return '<%s lines=%i>' % (object.__repr__(self), len(self.data))
#We also define a function to convert to string just for convenience
#It will simply join the list back together and return it
def __str__(self):
return '\n'.join(self.data)
#This is just a child of list_of_lines
class some_child_of_list_of_lines(list_of_lines):
pass
#We create the original list here with a string of 4 lines
original = list_of_lines('''
Hello
World
''')
#Here we use original as the argument when attempting to create a
# list_of_lines
casted = list_of_lines(original)
#casted is a reference to original
copy = list_of_lines(str(original))
#copy is a new instance of list_of_lines, identical to original
child_cast = some_child_of_list_of_lines(original)
#child_cast is identical to variable casted
#Note that the result here is actually an instance of the parent class
# of some_child_of_list_of_lines which one might not expect when
# calling some_child_of_list_of_lines but that is how this example
# turned out and one could modify the condition to do something
# more or less reasonable
child_copy = some_child_of_list_of_lines(str(original))
#child_copy is an instance of some_child_of_list_of_lines,
# identical to original
#Just present the variables so we can compare the addresses
# and types of them
print('''Results:
original: %(original)r
casted: %(casted)r
copy: %(copy)r
child_cast: %(child_cast)r
child_copy: %(child_copy)r
''' % vars())
#Output example
#original: <<__main__.list_of_lines object at 0x7f458cc8ad38> lines=4>
#casted: <<__main__.list_of_lines object at 0x7f458cc8ad38> lines=4>
#copy: <<__main__.list_of_lines object at 0x7f458cc642b8> lines=4>
#child_cast: <<__main__.list_of_lines object at 0x7f458cc8ad38> lines=4>
#child_copy: <<__main__.some_child_of_list_of_lines object at 0x7f458b3bdd88> lines=4>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment