class PyconStr(str):
pass
# Magic code
s = PyconStr(" bonjour ", "Pycon")
print(s) # " bonjour "
s = s.strip().shout().capitalize()
print(s) # "Bonjour!"
class JolieStr:
def __init__(self, content, info):
self._content = content
self._info = info
s = JolieStr(" bonjour ", "Pycon").strip().shout().capitalize()
print(s) # "Bonjour!"
class JolieStr:
def __init__(self, content, info):
self._content = content
self._info = info
def capitalize(self):
self._content = self._content.capitalize()
return self
def shout(self):
self._content = self._content + '!'
return self
def strip(self):
self._content = self._content.strip()
return self
def __repr__(self):
return self._content
s = JolieStr(" bonjour ", "Pycon")
print(s) # " bonjour "
s = s.strip().shout().capitalize()
print(s) # "Bonjour!"
class BasicStr(str):
def __init__(self, content, info):
super().__init__(content)
self._info = info
s = BasicStr(" bonjour ", "Pycon")
print(s)
Traceback (most recent call last):
File "pyconfr2019isawesome.py", line 6, in module
s = BasicStr(" bonjour ", "Pycon")
TypeError: decoding str is not supported
class BasicStr(str):
def __init__(self, content, info):
print("Hello there!", content)
super().__init__(content)
self._info = info
Traceback (most recent call last):
File "pyconfr2019isawesome.py", line 6, in module
s = BasicStr(" bonjour ", "Pycon")
TypeError: decoding str is not supported
object.__init__(self[, ...]):
Called after the instance has been created (by __new__()), but before it is returned to the caller.
object.__new__(cls[, ...]):
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.
class NewStr(str):
def __new__(cls, content, info):
obj = super().__new__(cls, content)
return obj
def __init__(self, content, info):
super().__init__()
self._info = info
def shout(self):
return self + "!"
s = NewStr(" bonjour ", "Pycon")
print(s)
print(s.upper())
print(s.shout())
s = NewStr(" bonjour ", "Pycon")
print(s)
print(s.upper())
print(s.shout())
bonjour
BONJOUR
bonjour !!
s = NewStr(" bonjour ", "Pycon")
print(s.shout().shout())
Traceback (most recent call last):
File "pyconfr2019isawesome.py", line 6, in module
print(s.shout().shout())
AttributeError: 'str' object has no attribute 'shout'
class NewStr(str):
def __new__(cls, content, info):
obj = super().__new__(cls, content)
return obj
def __init__(self, content, info):
super().__init__()
self._info = info
def shout(self):
return NewStr(self + "!", self._info)
print(s.shout().shout())
bonjour !!!!
print(s.upper().shout())
Traceback (most recent call last):
File "pyconfr2019isawesome.py", line 6, in module
print(s.upper().shout())
AttributeError: 'str' object has no attribute 'shout'
class InterceptStr(str):
def __new__(cls, content, info):
obj = super().__new__(cls, content)
return obj
def __init__(self, content, info):
super().__init__()
self._info = info
def __getattribute__(self, name):
if name in dir(str): # only handle str methods here
return # the right function
else: # do the usual thing
return super().__getattribute__(name)
def shout(self):
return InterceptStr(self + "!", self._info)
object.__getattribute__(self, name):
Called unconditionally to implement attribute accesses for instances of the class.
class InterceptStr(str):
def applyfunction(self, funcname, *args, **kwargs):
value = getattr(super(), funcname)(*args, **kwargs)
if isinstance(value, str):
return InterceptStr(value, self._info)
return value
def __getattribute__(self, name):
if name in dir(str): # only handle str methods here
return functools.partial(self.applyfunction, name)
else: # do the usual thing
return super().__getattribute__(name)
s = InterceptStr(" bonjour ", "Pycon")
print(s) # ' bonjour '
print(s.upper()) # ' BONJOUR '
print(s.shout()) # ' bonjour !'
print(s.shout().shout()) # ' bonjour !!'
print(s.upper().shout()) # ' BONJOUR !'
print(s.shout().split('j')) # [' bon', 'our !']
class PyconStr(str):
def __new__(cls, content, info):
obj = super().__new__(cls, content)
return obj
def __init__(self, content, info):
super().__init__()
self._info = info
def applyfunction(self, funcname, *args, **kwargs):
value = getattr(super(), funcname)(*args, **kwargs)
if isinstance(value, str):
return PyconStr(value, self._info)
return value
def __getattribute__(self, name, *args, **kwargs):
if name in dir(str): # only handle str methods here
return functools.partial(self.applyfunction, name)
else: # do the usual thing
return super().__getattribute__(name)
def shout(self):
return PyconStr(self + "!", self._info)
class JolieStr:
def __init__(self, content, info):
self._content = content
self._info = info
def shout(self):
self._content = self._content + '!'
return self
def applyfunction(self, name, *args, **kwargs):
self._content = getattr(self._content, name)(*args, **kwargs)
return self
def __getattribute__(self, name):
if name in dir(str): # only handle str methods here
return functools.partial(self.applyfunction, name)
else:
return super().__getattribute__(name)
def __repr__(self):
return str(self._content)
s = JolieStr(" bonjour ", "Pycon")
print(s) # ' bonjour '
print(s.upper().shout()) # ' BONJOUR !'
print(s.shout().split('j')) # [' bon', 'our !']