469,332 Members | 6,874 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,332 developers. It's quick & easy.

is it possible to give an instance a value?

Hi,

My question probably reflects my misunderstanding of python objects,
but I would still like to know the answer.

The question is, is it possible for an instnace to have a value (say a
string, or integer) that can interact with other datatypes and be
passed as an argument?

The following code of course gives an error:

class Test(object):
def __init__(self, val):
self.val = val
>>a = Test('hello')
a.val + ' happy'
'hello happy'
>>a + 'happy'
TypeError: unsupported operand type(s) for +: 'Test' and 'str'

Is there a way to make a have the value a.val when it is used as
above, or as an argument (eg function(a, 10, 'sdf') etc)?

The only fudge I discovered for simple addition was to add to the
class

def __add__(self, obj):
return a.val + obj

but this doesn't solve the problem in general. I have tried
subclassing the string type, but as it is immutable, this is not
flexible the way a.val is (i.e. it can't e reassigned and remain a
subclass).

Any pointers, or is my question wrong-headed?

btw, my motivation is wanting to mimic another oo language which
allows this, so it allows:
>>>Person.Address
'Sydney'
>>>Person.Address.type
'%String'
>>>Person.Address = 'Canberra'
print Person.Address. Person.Address.type
Canberra %String

etc.

We have had to implement Person.Address as Person.Address.val, making
Address an instance with .val, .type, etc.

Mar 6 '07 #1
9 1461

"manstey" <ma*****@csu.edu.auwrote in message
news:11**********************@v33g2000cwv.googlegr oups.com...
| Hi,
|
| My question probably reflects my misunderstanding of python objects,
| but I would still like to know the answer.
|
| The question is, is it possible for an instnace to have a value (say a
| string, or integer) that can interact with other datatypes and be
| passed as an argument?

In the way you are asking, no.

| Is there a way to make a have the value a.val when it is used as
| above, or as an argument (eg function(a, 10, 'sdf') etc)?
|
| The only fudge I discovered for simple addition was to add to the
| class
|
| def __add__(self, obj):
| return a.val + obj
|
| but this doesn't solve the problem in general. I have tried
| subclassing the string type, but as it is immutable, this is not
| flexible the way a.val is (i.e. it can't e reassigned and remain a
| subclass).

Special methods are the Python way, not a fudge. Consider
>>dir(1)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__',
'__hex__', '__init__', '__int__', '__invert__', '__long__', '__lshift__',
'__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__',
'__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__',
'__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__',
'__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__',
'__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__',
'__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']

All these int methods do the C equivalent of return int(self.val +
other.val), etc. Similarly, the reason an int object with value 123 prints
as 123 instead of <int object at 0xXXXXXXis because the C coded __str__
extracts the value field of the int structure and converts it to ascii.

Terry Jan Reedy

Mar 6 '07 #2
manstey a écrit :
Hi,

My question probably reflects my misunderstanding of python objects,
but I would still like to know the answer.

The question is, is it possible for an instnace to have a value (say a
string, or integer) that can interact with other datatypes and be
passed as an argument?
In Python, strings and integers *are* objects (instances of resp. str
and int).
The following code of course gives an error:

class Test(object):
def __init__(self, val):
self.val = val

>>>>a = Test('hello')
a.val + ' happy'

'hello happy'
>>>>a + 'happy'

TypeError: unsupported operand type(s) for +: 'Test' and 'str'
No surprise so far.
Is there a way to make a have the value a.val
Forget about the value/instance distinction - it doesn't exists in Python.
when it is used as
above,
implement __add__ (and any other appropriate magic method)
or as an argument (eg function(a, 10, 'sdf') etc)?

The only fudge I discovered for simple addition was to add to the
class

def __add__(self, obj):
return a.val + obj
So what's your problem exactly ?
but this doesn't solve the problem in general. I have tried
subclassing the string type, but as it is immutable, this is not
flexible the way a.val is
Err... In your above example implementation, a.val actually *is* a string.
(i.e. it can't e reassigned
???

a.val = "tutu"
and remain a
subclass).
???
Any pointers, or is my question wrong-headed?
I'm afraid I don't get the point.
btw, my motivation is wanting to mimic another oo language which
allows this, so it allows:
>>>>Person.Address

'Sydney'
>>>>Person.Address.type

'%String'
>>>>Person.Address = 'Canberra'
print Person.Address. Person.Address.type

Canberra %String

etc.
We have had to implement Person.Address as Person.Address.val, making
Address an instance with .val, .type, etc.
>>class Person(object):
.... def __init__(self):
.... self.address = "sidney"
....
>>person = Person()
person.address
'sidney'
>>type(person.address)
<type 'str'>
>># this is equivalent:
person.address.__class__
<type 'str'>
>># of if you want the name of the class instead
# of the class object itself:
person.address.__class__.__name__
'str'
>>>

Looks like you'd better learn the Python way instead of wasting your
time trying to mimic some other language (BTW, is it VB or C# ?).

HTH
Mar 6 '07 #3
On Mar 6, 2:45 pm, "manstey" <mans...@csu.edu.auwrote:
The question is, is it possible for an instance to have a value (say a
string, or integer) that can interact with other datatypes and be
passed as an argument?

The following code of course gives an error:

class Test(object):
def __init__(self, val):
self.val = val
>a = Test('hello')
a.val + ' happy'
'hello happy'
>a + 'happy'

TypeError: unsupported operand type(s) for +: 'Test' and 'str'

Is there a way to make a have the value a.val when it is used as
above, or as an argument (eg function(a, 10, 'sdf') etc)?

The only fudge I discovered for simple addition was to add to the
class

def __add__(self, obj):
return a.val + obj

but this doesn't solve the problem in general. I have tried
subclassing the string type, but as it is immutable, this is not
flexible the way a.val is (i.e. it can't e reassigned and remain a
subclass).

Any pointers, or is my question wrong-headed?

btw, my motivation is wanting to mimic another oo language which
allows this, so it allows:
>>Person.Address
'Sydney'
>>Person.Address.type
'%String'
>>Person.Address = 'Canberra'
print Person.Address. Person.Address.type

Canberra %String

etc.

We have had to implement Person.Address as Person.Address.val, making
Address an instance with .val, .type, etc.
The question is not, "is it possible for an instance to have a
value?", but "is it possible for a value to have other attributes?" If
you really need them, you want Python descriptors, which are described
here: http://docs.python.org/ref/descriptors.html. However, if type is
the only value metadata you care about, you probably don't need them
(just use the builtin 'type' function on any object).
class TypedAttribute(object):

def __init__(self, type=unicode):
self.type = type

def __get__(self, obj, unitclass=None):
if obj is None:
# When calling on the class instead of an instance...
return self
else:
return obj._attributes[self.key]

def __set__(self, obj, value):
obj._attributes[self.key] = value

def __delete__(self, obj):
raise AttributeError("TypedAttributes may not be deleted.")
class Person(object):

Address = TypedAttribute(str)

def __init__(self):
self._attributes = {}
I'm using the _attributes dict here just by convention; I find it
convenient to store the underlying values in each parent object. There
are other ways to do it.
Robert Brewer
System Architect
Amor Ministries
fu******@amor.org

Mar 7 '07 #4
On Tue, 06 Mar 2007 14:45:45 -0800, manstey wrote:
class Test(object):
def __init__(self, val):
self.val = val
>>>a = Test('hello')
a.val + ' happy'
'hello happy'
>>>a + 'happy'
TypeError: unsupported operand type(s) for +: 'Test' and 'str'

Is there a way to make a have the value a.val when it is used as
above, or as an argument (eg function(a, 10, 'sdf') etc)?
That's kinda-sorta like "delegation", which is an alternative to
sub-classing. Whether you subclass string or delegate to a string, the end
result will be the same, only the implementation will be different.

However, while sub-classing str will give you an immutable object,
delegation can give you a mutable string. See UserString.MutableString for
details -- but beware that this is significantly slower than ordinary
strings.

Honestly, once you've been using immutable strings for a while, you'll
rarely care that they aren't mutable.
The only fudge I discovered for simple addition was to add to the
class

def __add__(self, obj):
return a.val + obj

but this doesn't solve the problem in general. I have tried
subclassing the string type, but as it is immutable, this is not
flexible the way a.val is (i.e. it can't e reassigned and remain a
subclass).
Because of the way Python works, you can't really expect this to work:
>>s = MyClass("something") # s is assigned an instance of MyClass
s = "ordinary string" # s magically remains a MyClass instance
Python just doesn't work that way. The name "s" can't force the object
"ordinary string" to be some other type. If you want "s" to have an
instance of MyClass assigned to it, you have to do it explicitly:
>>s = MyClass("ordinary string") # not ordinary any more

If you are willing to write s.data instead of s, then you can make the
data attribute a property and automate most of that.
class MyString(str):
pass # customise the behaviour you want to see

class MyClass(object):
def __init__(self, data):
self.data = data
def _getter(self):
return self._data
def _setter(self, data):
self._data = MyString(data)
data = property(_getter, _setter, None, None)
Now you can do this:
>>inst = MyClass("hello world")
inst.data += "!"
type(inst.data)
<class '__main__.MyString'>
>>inst.data = "Nobody expects the Spanish Inquisition!"
type(inst.data)
<class '__main__.MyString'>

But this doesn't work:
>>inst = "dead parrot"
type(inst) == MyClass # what we want to be True
False
But chances are that all of that scaffolding (delegation, properties,
etc.) would be unnecessary if you just change the way you do things. E.g.
instead of your example:
>>Person.Address
'Sydney'
>>Person.Address.type
'%String'

Python can do this:
>>Person.Address
'Sydney'
>>type(Person.Address)
<type 'str'>

If you sub-classed str like this:

class MyString(object):
def __init__(self, data, type="%String"):
self.data = data
self.type = type

hoping to use it like this:
>>fred = Person("Address", "Sydney", "%String") # or something...
fred.Address
'Sydney'
>>fred.Address.type
'%String'

then you're just making work for yourself.
Hope this makes sense.
--
Steven D'Aprano

Mar 7 '07 #5
On Tue, 06 Mar 2007 14:45:45 -0800, manstey wrote:
>
class Test(object):
def __init__(self, val):
self.val = val

a = Test('hello')
Is there a way to make a have the value a.val when it is used as
above, or as an argument (eg function(a, 10, 'sdf') etc)?
My impression is that you can do everything you want to
by making your instance callable, and not using a but a().

This is just an example:

class Persoon(object):
def __init__(self, adres):
self.adres=adres

def __call__(self, new_adres=None):
if new_adres: self.adres = new_adres
return self.adres

a = Persoon("Sidney")
print "Living in " + a()
a("Canberra")
print "Living in " + a()
print "Now living in ", a("Amsterdam")
print "Type of a() is: %s" % type(a())
print "Now earning" , a(1234) + 500
print "Type of a() is: %s" % type(a())
print "string ? %s" % ["No","Yes"][isinstance(a(), basestring)]

The output is:

Living in Sidney
Living in Canberra
Now living in Amsterdam
Type of a() is: <type 'str'>
Now earning 1734
Type of a() is: <type 'int'>
string ? No
e
--
Egbert Bouwman - Keizersgracht 197 II - 1016 DS Amsterdam - 020 6257991
================================================== ======================
Mar 7 '07 #6
Thanks everyone for your replies. The language is Cache Object Script,
a language used in Intersystems Relational Dbase.

I think egbert's answer provides the simplest answer. It allows our
python interface to Cache to be almost identical to Cache Object
Script, with simeply the addition of (), which we prefer to .val
or .data for various reasons.

Using the example .type was a mistake, as I meant simply any metadata
about a value. If we make the instance callable, then we can have:

instance()
instance.calculated
instance.type
instance.whatever
instance.save()
etc

thanks.

Mar 8 '07 #7
On Wed, 07 Mar 2007 16:02:05 +0100, egbert wrote:
On Tue, 06 Mar 2007 14:45:45 -0800, manstey wrote:
>>
class Test(object):
def __init__(self, val):
self.val = val

a = Test('hello')
>Is there a way to make a have the value a.val when it is used as
above, or as an argument (eg function(a, 10, 'sdf') etc)?
My impression is that you can do everything you want to
by making your instance callable, and not using a but a().
You can't do this:
>>a() = "some value"
SyntaxError: can't assign to function call
If you do this:
>>a = "some value"
then we're back to the Original Poster's original problem.

--
Steven D'Aprano

Mar 8 '07 #8
On Thu, Mar 08, 2007 at 01:22:25PM +1100, Steven D'Aprano wrote:
On Wed, 07 Mar 2007 16:02:05 +0100, egbert wrote:
My impression is that you can do everything you want to
by making your instance callable, and not using a but a().
You can't do this:
>a() = "some value"
I didn't say that you can do that.
But in my example you can do
>> a("some value")
and that seems to be near enough for manstey.
e
--
Egbert Bouwman - Keizersgracht 197 II - 1016 DS Amsterdam - 020 6257991
================================================== ======================
Mar 8 '07 #9
In article <45***********************@news.free.fr>,
Bruno Desthuilliers <bd*****************@free.quelquepart.frwrote:
>manstey a écrit :
>>
Is there a way to make a have the value a.val

Forget about the value/instance distinction - it doesn't exists in Python.
Actually, I think it does. For example, int('123') has the value 123.
The way I would put it, any type/class that has an eval()able
representation has a value.
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

"I disrespectfully agree." --SJM
Mar 14 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Jeff Lanfield | last post: by
reply views Thread by dag | last post: by
3 posts views Thread by Steven W. Orr | last post: by
5 posts views Thread by Sin Jeong-hun | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by Marylou17 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.