0

I know how to override string class with:

class UserString:
    def __str__(self):
        return 'Overridden String'

if __name__ == '__main__':
    print UserString()

But how can i use this class instead of built-in str class without defining implicitly UserString class?. To be clear I want this:

>>> print "Boo boo!"
Overridden String
guneysus
  • 6,203
  • 2
  • 45
  • 47
  • 4
    It's not possible. You have not "overridden string class", you have defined a class whose instances can be converted to strings. You can't change the type of string literals. – Steve Jessop Jan 02 '14 at 14:23
  • Do you want to use the class? Or are you simply interested on overriding `print`? – Aziz Alfoudari Jan 02 '14 at 14:32
  • I am trying to found a new way -that would be integrate seamlessly- to uppercase special Turkish unicode characters. In other words, when a `MYSTRING.upper()` method triggerer, I want to trigger my own `upper()` method. – guneysus Jan 02 '14 at 15:07

2 Answers2

2

It is not possible. You have not overridden string class.

You cannot override classes. You can override methods. What you have done is defined a class and only overridden its str() method.

But you can do something like this...

def overriden_print(x):
    print "Overriden in the past!"

from __future__ import print_function  # import after the definition of overriden_print

print = overriden_print

print("Hello")

Output:

Overriden in the past!

Buddhima Gamlath
  • 2,318
  • 1
  • 16
  • 26
1

It's impossible to do what you want without hacking the python executable itself... after all, str is a built-in type, and the interpreter, when passed 'string' type immediates, will always create built-in strings.

However... it is possible, using delegation, to do something like this. This is slightly modified from another stackoverflow recipe (which sadly, I did not include a link to in my code...), so if this is your code, please feel free to claim it :)

def returnthisclassfrom(specials):
  specialnames = ['__%s__' % s for s in specials.split()]
  def wrapit(cls, method):
    return lambda *a: cls(method(*a))
  def dowrap(cls):
    for n in specialnames:
      method = getattr(cls, n)
      setattr(cls, n, wrapit(cls, method))
    return cls
  return dowrap

Then you use it like this:

@returnthisclassfrom('add mul mod')
class UserString(str):
    pass

In [11]: first = UserString('first')

In [12]: print first
first

In [13]: type(first)
Out[13]: __main__.UserString

In [14]: second = first + 'second'

In [15]: print second
firstsecond

In [16]: type(second)
Out[16]: __main__.UserString

One downside of this is that str has no radd support, so 'string1' + UserString('string2') will give a string, whereas UserString('string1') + 'string2' gives a UserString. Not sure if there is a way around that.

Maybe not helpful, but hopefully it puts you on the right track.

Corley Brigman
  • 11,633
  • 5
  • 33
  • 40
  • Thanks, this is not the exactly i am looking for but i liked it, because, it uses decorators. And your code looks like http://stackoverflow.com/a/1243045/1766716 :) – guneysus Jan 02 '14 at 15:15
  • that's the one... thanks for finding that! (annotating in code now...) – Corley Brigman Jan 02 '14 at 15:39