Subclass str: where is the problem?

P

pascal.parent

Hello, can anybody explain/help me:

Python 2.4.2 (#2, Sep 30 2005, 21:19:01)
[GCC 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu8)] on linux2


class Upper(str):
def __new__(cls, value):
return str.__new__(cls, value.upper())

u = Upper('test')
u
'TEST'
type(u)
<class '__main__.Upper'>
u = Upper('')
u
''
type(u)
<class '__main__.Upper'>


All seems to be ok...

class MyObject(object):
def __init__(self, dictionary = {}):
self.id = dictionary.get('id', '')
def __setattr__(self, attribute, value):
value = type(value) is type('') and Upper(value) or value
object.__setattr__(self, attribute, value)

m = MyObject({'id': 'test'})
m.id
'TEST'
type(m.id)
<class '__main__.Upper'>
m = MyObject()
m.id
''
type(m.id)
<type 'str'>

Why is m.id a str ?
Thanks.
 
H

harold

Hello, can anybody explain/help me:

Python 2.4.2 (#2, Sep 30 2005, 21:19:01)
[GCC 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu8)] on linux2


class Upper(str):
def __new__(cls, value):
return str.__new__(cls, value.upper())

u = Upper('test')
u
'TEST'
type(u)
<class '__main__.Upper'>
u = Upper('')
u
''
type(u)
<class '__main__.Upper'>


All seems to be ok...

class MyObject(object):
def __init__(self, dictionary = {}):
self.id = dictionary.get('id', '')
def __setattr__(self, attribute, value):
value = type(value) is type('') and Upper(value) or value
object.__setattr__(self, attribute, value)

m = MyObject({'id': 'test'})
m.id
'TEST'
type(m.id)
<class '__main__.Upper'>
m = MyObject()
m.id
''
type(m.id)
<type 'str'>

Why is m.id a str ?

Because Upper(value) will be False in the line
value = type(value) is type('') and Upper(value) or value
and thus, you assign value itself to value again.
rewrite it for exmaple in this way:

def __setattr__(self, attribute, value):
if type(value) is type('') :
value = Upper(value)
object.__setattr__(self, attribute, value)
 
P

pascal.parent

This is good... try this:

value = 'test'
value
'test'
type(value)
<type 'str'>
value = type(value) is type('') and Upper(value) or value
value
'TEST'
type(value)
<class '__main__.Upper'>

value = 1
value
1
type(value)
<type 'int'>
value = type(value) is type('') and Upper(value) or value
value
1
type(value)
<type 'int'>
 
P

Peter Otten

This is good... try this:

value = 'test'
value
'test'
type(value)
<type 'str'>
value = type(value) is type('') and Upper(value) or value
value
'TEST'
type(value)
<class '__main__.Upper'>

Try again with

value = ""

This makes Upper(value) a False value in a boolean context:
.... pass
....<type 'str'>

versus
<class '__main__.Upper'>

Peter
 
H

harold

Hi Pascal,

Indeed, the example you show work corrctly. But in the
code you posted before, you wonder about the behavior
of these lines:
m = MyObject()
m.id
''
type(m.id)
<type 'str'>

So what happens when you provide the empty string '' to your and-or
construct?
value = ''
value = type(value) is type('') and Upper(value) or value

As you can easily check, bool('') resolves to False. Thus, your line
becomes:
value = False and False or value
Python first evaluates the and expression, which resolves to False. The
or
expression evaluates the second argument and returns that one as the
result
if and only if the first one evaluates to False, which is the case
here. So the
result of False or value is value. You can check thatTrue
so, in you code, the empty string gets indeed assign as value again.

Be carefull with the condition/and/or chain! You must be 110% sure,
that
the desired return value in case of condition==True can never evaluate
to False!

- harold -
 

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,777
Messages
2,569,604
Members
45,208
Latest member
RandallLay

Latest Threads

Top