Add methods to string objects.

N

Negroup

Hi all.
I'm writing a simple Python module containing functions to process
strings in various ways. Actually it works importing the module that
contains the function I'm interested in, and calling
my_module.my_function('mystring').

I was just asking if it is possible to "extend" string objects'
behaviour so that it becomes possible to invoke something like
'anystring'.my_method().

1) does the latter approach bring some advantages?
2) how is it possible to achieve this goal?

Any pointer will be appreciated, thanks.
 
R

Roy Smith

I was just asking if it is possible to "extend" string objects'
behaviour so that it becomes possible to invoke something like
'anystring'.my_method().

You can't quite do that, but you can get close. You can define your own
class which inherits from str, and then create objects of that class. For
example:

class myString (str):
def __init__ (self, value):
self.value = value

def plural (self):
if self.value[-1] in "sz":
return self.value + "es";
else:
return self.value + "s";

foo = myString("foo")
bar = myString("bar")
baz = myString("baz")

print foo.plural(), bar.plural(), baz.plural() # my defined method
print foo.capitalize() # inherited from base class
 
S

simon.dahlbacka

You can even get closer, but it is NOT recommended

class foostr(str):
def plural (self):
if self.value[-1] in "sz":
return self.value + "es"
else:
return self.value + "s"


#ugly hack
setattr(__builtins__, "str", foostr)

print str("apple").plural()

# this however does not work
# print "apple".plural()
 
M

Magnus Lycka

Negroup said:
Hi all.
I'm writing a simple Python module containing functions to process
strings in various ways. Actually it works importing the module that
contains the function I'm interested in, and calling
my_module.my_function('mystring').

I was just asking if it is possible to "extend" string objects'
behaviour so that it becomes possible to invoke something like
'anystring'.my_method().

The proper way is to extend the string type by subclassing it:

class S(str):
def my_method(self):
...

Then you can do "S('anystring').my_method()" etc.

Example:
.... def lowers(self):
.... return filter(lambda x:x!=x.upper(), self)
.... def uppers(self):
.... return filter(lambda x:x!=x.lower(), self)
....elloorld

This means that your additional behaviour isn't available to
plain string literals. You need to instanciate S objects. This
is much less confusing for other programmers who read your code
(or for yourself when you read it a few years from now).
 
R

Roy Smith

You can even get closer, but it is NOT recommended

class foostr(str):
def plural (self):
if self.value[-1] in "sz":
return self.value + "es"
else:
return self.value + "s"


#ugly hack
setattr(__builtins__, "str", foostr)

print str("apple").plural()

# this however does not work
# print "apple".plural()

It's fascinating that the setattr() works (and I agree with you that it's a
bad idea), but given that it does work, why doesn't it work with a string
literal?
 
R

Rocco Moretti

Roy said:
You can even get closer, but it is NOT recommended

class foostr(str):
def plural (self):
if self.value[-1] in "sz":
return self.value + "es"
else:
return self.value + "s"


#ugly hack
setattr(__builtins__, "str", foostr)

print str("apple").plural()

# this however does not work
# print "apple".plural()


It's fascinating that the setattr() works (and I agree with you that it's a
bad idea), but given that it does work, why doesn't it work with a string
literal?

Because the string literal is the *actual* C-level builtin string type,
not whatever type happens to be in __builtins__.str at the time. ("At
the time" is also a tricky proposition - string literals are made into
obects at compile time, before __builtins__ is twiddled with.)

BTW, on setattr():

'''
setattr( object, name, value)

This is the counterpart of getattr(). The arguments are an object, a
string and an arbitrary value. The string may name an existing attribute
or a new attribute. The function assigns the value to the attribute,
provided the object allows it. For example, setattr(x, 'foobar', 123) is
equivalent to x.foobar = 123.
'''

i.e. '''setattr(__builtins__, "str", foostr)''' is the same as
'''__builtins__.str = foostr''', but I would agree that the setattr
gives more of a "black magic" warning.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top