Last active
March 19, 2017 03:21
-
-
Save devilholk/3732e7c05264d489cf31349f036c556c to your computer and use it in GitHub Desktop.
Example usage of the __new__ method of python objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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