473,406 Members | 2,273 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Object default value

ago
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)

Example:

class obj(object):
x=1 #assume x is somehow made into a default value
y=2

Ideally this should be the result:

myobj=obj()
print myobj #-> 1
print myobj.y #-> 2
x=myobj
print x #-> 1
print type(x) #int

Those are my half-working solutions so far:

1) using __get__ descriptor within the class,

def __get__(self,parent,parenttype): return self.x

then

print myobj #works
print myobj.y #does not work! equivalent to: print 1.y

2) Use a __call__ method without a __get__ descriptor.

def __call__(self): return self.x

then:

print myobj() #works, but not the same as: print myobj
print myobj.y #works

Sep 20 '05 #1
14 2394
The prints can be done by defining an __str__ method on the
class, but I don't think you will get the type(obj) to work
the way you want.

class obj(object):
__default=1
y=2

def __str__(self):
return str(self.__default)

myobj=obj()
print "myobj=", myobj
print "myobj.y=", myobj.y
myobj= 1
myobj.y= 2

ago wrote: Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)

Example:

class obj(object):
x=1 #assume x is somehow made into a default value
y=2

Ideally this should be the result:

myobj=obj()
print myobj #-> 1
print myobj.y #-> 2
x=myobj
print x #-> 1
print type(x) #int

Those are my half-working solutions so far:

1) using __get__ descriptor within the class,

def __get__(self,parent,parenttype): return self.x

then

print myobj #works
print myobj.y #does not work! equivalent to: print 1.y

2) Use a __call__ method without a __get__ descriptor.

def __call__(self): return self.x

then:

print myobj() #works, but not the same as: print myobj
print myobj.y #works

Sep 20 '05 #2
ago
The print statement was only for illustrative purposes, when calling
varx=myobj I need to receive obj.x as opposed to the instance of obj,
but I also need to call vary=myobj.y. Something like that exists for
com objects/VB, for instance an excel range object uses value as the
default attribute, so that you can write

set rng=range(...);
x=rng
y=rng.value
'x==y
z=rng.attributeXYZ

Sep 20 '05 #3
I think you want to overload the assignment operator here. I'm not sure that
is allowed in python (I've never seen it done). You can overload the
equality, lt, gt, le, ge operators (==, <, ...) such that

class Thing:
x = 5
def __str__(self):
return str(self.x)
def __eq__(self, other):
if hasattr(other, 'x'):
return self.x == other.x
else:
return self.x == other

py> athing = Thing()
py> athing.x
5
py> bob = athing.x
py> athing == bob # having overlaoded equality for athing
True
py> athing is bob # not the same object
False

But I don't think assignment overloading is allowed in python:

py> athing = Thing()
py> print athing # having overloaded __str__()
5
py> bob = athing
py> type(bob) # will not be an int ==> python language constraint
<type 'instance'>

James

On Tuesday 20 September 2005 13:05, ago wrote:
The print statement was only for illustrative purposes, when calling
varx=myobj I need to receive obj.x as opposed to the instance of obj,
but I also need to call vary=myobj.y. Something like that exists for
com objects/VB, for instance an excel range object uses value as the
default attribute, so that you can write

set rng=range(...);
x=rng
y=rng.value
'x==y
z=rng.attributeXYZ


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Sep 20 '05 #4
See this recent clpy thread:

http://www.thescripts.com/forum/thread19253.html

On Tuesday 20 September 2005 13:05, ago wrote:
The print statement was only for illustrative purposes, when calling
varx=myobj I need to receive obj.x as opposed to the instance of obj,
but I also need to call vary=myobj.y. Something like that exists for
com objects/VB, for instance an excel range object uses value as the
default attribute, so that you can write

set rng=range(...);
x=rng
y=rng.value
'x==y
z=rng.attributeXYZ


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Sep 20 '05 #5
> I think you want to overload the assignment operator here. I'm not sure
that
is allowed in python (I've never seen it done).


You can't because assignment is not an operator in Python.

Is it safe to assume that the OP's next question will be how to invoke
functions without the ()'s? To save you the trouble, then answer is 'no'.

Python is simple, VB is simple, but Python is not VB.

-- Paul
Sep 20 '05 #6
ago wrote:
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)


You're descriptions aren't very clear. Maybe you can put that in a
greater context - what do you want to achieve?

And the assignment-operator isn't overloadable - that is for sure!

Diez
Sep 20 '05 #7
ago
I am trying to write a generic DataAttribute class in order to simplify
access to object attributes and attached attribute-metadata for end
users with little programming experience.

Requirement 1: accessing the "default" value should be easy (using
assignment operator, via descriptors like __get__ and __set__).

Requirement 2: access to the attribute-metadata should also be as
intuitive as possible.

Requirement 3: possibly the DataAttribute should also be callable, to
return for instance, an history of its values.

class DataAttribute(object):
value=1 #default
old=2
....

class Obj(object): attr=DataAttribute()

#From end user prospective, ideally:
obj=Obj()
x = obj.attr #x=1
xold = obj.attr.old #xold=2
obj.attr = 3 #obj.attr.value=3
xold = obj.attr.old #xold=1
xhistory = obj.attr(startdate, enddate) #xhistory = [[date1,
4],[date2,5],[date3,6]]
xtimestmap = x.attr.timestamp
print obj.attr == obj.attr.value #True

If I use __get__ then I cannot access the metadata.

I could create a separate Obj attribute for each metadata item, but
then I would litter the Obj namespace (typical object will have several
attributes each with lots of metadata) and potentially create name
conflicts. Not to mention that DataAttributes should be
attached/deleted on the fly and if each attribute becames a set of
attributes this operation is complex (metclasses?).

If I use __call__ + __set__ but then I am introducing an asymmetry:

x = obj.attr()
obj.attr = 2

I could use getters and setters but that is not really convenient nor
intuitive

Sep 20 '05 #8
ago
> Is it safe to assume that the OP's next question will be how to invoke
functions without the ()'s? To save you the trouble, then answer is
'no'.

You probably nailed it, thanks for the answer. I suspected that was the
case. I think I'll use __call__ + __set__

Sep 20 '05 #9
ago
In fact even IF I could get a default value to work as mentioned, then
I would be creating potential name conflicts between the
DataAttribute.DefaultValue and the other metadata. I.e. when calling
obj.attr.x I could refer to DataAttribute.x or DataAttribute.value.x.
It's a no go.

Sep 20 '05 #10
James Stroud wrote:
I think you want to overload the assignment operator here. I'm not sure that
is allowed in python (I've never seen it done)....
But I don't think assignment overloading is allowed in python:


Exactly correct. Assignment is an operation on a namespace using a new
value, and does not involve the former value. Something similar to
assignment overloading is possible with properties, but you need to be
using object attributes, not names in a module (or function locals).

class SomeDemo(object):
def _read_foo(self):
print 'Reading foo'
return self._foo

def _write_foo(self, value):
print 'Writing foo as %r' % value
return self._foo

def _del_foo(self):
print 'Deleting foo'
del self._foo

foo = property(_read_foo, _write_foo, _del_foo)

obj = SomeDemo()
obj.foo = 123
obj.foo += 1
del obj.foo

--Scott David Daniels
Sc***********@Acm.Org
Sep 20 '05 #11
"ago" <ag************@gmail.com> wrote:
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)


No.

You can overload certain methods to make an object behave like one
of its attributes in certain contexts (e.g. comparisions, math operations,
conversions), but you cannot do it for all operations.

Especially not the "assignment operator", since there is no such thing in
Python. (assignment is a statement, and it's an operation on the target
namespace, not the source object).

(As always, Python works better if you use it to write Python programs)

</F>

Sep 21 '05 #12
On Tuesday 20 September 2005 12:31, ago wrote:
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)


I was thinking about this last night and it seemed an interesting problem. I
thought you might want to change the way you look at it, using the python
equivalent to type casting (maybe its called "coercing", sorry for my poor
command of python vocabulary). I have overridden __int__ and __float__ for
this example. You might want to look into __coerce__. This should have the
behavior you desire while having the explicit syntax expected of good python
code.

Inheriting from list allows you to use a stack-like behavior you described in
a previous email. You can further modify __getattribute__, __setattribute__,
__delattribute__, etc. Overriding __iter__ gives you the history in "correct"
order, but may begin to embark on a non-intuitive interface--you be the
judge. I think this is about as close as you can get in python to what you
are thinking (don't know the oldest python version this is backwards
compatible with):
py> class Thing(list):
.... def __init__(self, start_value):
.... list.__init__(self)
.... self.append(start_value)
.... def __setattr__(self, anattr, aval):
.... if (anattr == 'top'):
.... self.append(aval)
.... else:
.... list.__setattr__(self, anattr, aval)
.... def __getattr__(self, anattr):
.... if (anattr == 'top'):
.... return self[-1]
.... elif (anattr == 'old'):
.... try:
.... return self[-2]
.... except IndexError:
.... raise NameError, "No old value yet"
.... else:
.... list.__getattr__(self, anattr)
.... def __iter__(self):
.... return list.__iter__(self[::-1])
.... def __int__(self):
.... return int(self.top)
.... def __float__(self):
.... return float(self.top)
.... def __str__(self):
.... return str(self.top)
....
py> athing = Thing(5) # should init with a reasonable value
py> athing.top # __getattr__
5
py> int(athing) # __int__
5
py> print athing # __str__
5
py> float(athing) # __float__
5.0
py> athing.top = 4 # __setattr__
py> print athing
4
py> athing.old # __getattr__
5
py> athing.top = 42 # __setattr__
py> [x for x in athing] # __iter__
[42, 4, 5]
py> y = float(athing) # closest you can get to assignment overloading
py> print y # y is a float
42.0
py> athing # Thing inherits from list, so you get list.__repr__() here
[5, 4, 42]

Here it is without the prompts:

class Thing(list):
def __init__(self, start_value):
list.__init__(self)
self.append(start_value)
def __setattr__(self, anattr, aval):
if (anattr == 'top'):
self.append(aval)
else:
list.__setattr__(self, anattr, aval)
def __getattr__(self, anattr):
if (anattr == 'top'):
return self[-1]
elif (anattr == 'old'):
try:
return self[-2]
except IndexError:
raise NameError, "No old value yet"
else:
list.__getattr__(self, anattr)
def __iter__(self):
return list.__iter__(self[::-1])
def __int__(self):
return int(self.top)
def __float__(self):
return float(self.top)
def __str__(self):
return str(self.top)

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Sep 21 '05 #13
On 20 Sep 2005 12:31:19 -0700, "ago" <ag************@gmail.com> wrote:
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)

Example:

class obj(object):
x=1 #assume x is somehow made into a default value
y=2

Ideally this should be the result:

myobj=obj() normal
print myobj #-> 1 expression myobj interpreted as myobj.x?
print myobj.y #-> 2 normal
x=myobj normal, because expression myobj in this context of immediate assignment does not mean myobj.x?
print x #-> 1 expression x is the same as expression myobj, which is intrpreted as myobj.x (alias x.x) if not assigned?
print type(x) #int ditto

If you wanted to have this effect inside a function, you could write a byte-code-munging
decorator to evaluate selected_name as selected_name.selected_attr except where
assigning to an alias name is all that a statement does, as in x = myobj.

But what if you actually wanted to pass the object per se somewhere, or return it from
a function? Maybe you could have the expression myobj.x mean the normal myobj, and vice
versa in a kind of terrible symmetry ;-)

Then usage might be something like
@agostino_effect(myobj='x') # eval myobj as myobj.x
def foo():
myobj=obj()
print myobj #-> 1
print myobj.y #-> 2
x = myobj
print x #-> 1
return x, myobj, x.y, myobj.x # with .x having "symmetrically-other" effect ;-)

xval, myobjval, x_dot_y_val, myobj_per_se = foo() # assignment from function is not interfered with
myobj_per_se.y #->2
myobj_per_se #-> 1
myobj_val.y -> AttributeError: 'int' object has no attribute 'y'

I'm not suggesting this is a good way to go forward, I am just playing with the feasibility of
doing what you want, even if it's not good for you ;-) I suspect there is a better way, but
it wouldn't be that hard to do the above, as you can see from the code of foo
that the agostino_effect decorator would be modifying:
def foo(): ... myobj=obj()
... print myobj #-> 1
... print myobj.y #-> 2
... x = myobj
... print x #-> 1
... return x, myobj, x.y, myobj.x # with .x having "symmetrically-other" effect ;-)
... import dis
dis.dis(foo)

2 0 LOAD_GLOBAL 0 (obj)
3 CALL_FUNCTION 0
6 STORE_FAST 0 (myobj)

3 9 LOAD_FAST 0 (myobj)
Here you'd notice that the next instruction was not STORE_FAST
so you'd insert a
LOAD_ATTR 1 (x)
similar to the .y access below

12 PRINT_ITEM
13 PRINT_NEWLINE

4 14 LOAD_FAST 0 (myobj)
17 LOAD_ATTR 2 (y)
Here you'd notice the above wasn't LOAD_ATTR (x) (which you'd otherwise have to remove for object-per-se)

20 PRINT_ITEM
21 PRINT_NEWLINE

5 22 LOAD_FAST 0 (myobj)
25 STORE_FAST 1 (x)
This you notice is an immediate assignment and you leave it alone, and note the alias

6 28 LOAD_FAST 1 (x)
Here you notice the alias and insert
LOAD_ATTR 1 (x)
as before with myobj

31 PRINT_ITEM
32 PRINT_NEWLINE

7 33 LOAD_FAST 1 (x)
insert
LOAD_ATTR 1 (x)
again
36 LOAD_FAST 0 (myobj)
insert
LOAD_ATTR 1 (x)
again
39 LOAD_FAST 1 (x)
42 LOAD_ATTR 2 (y)
other attribute, no change to above byte code
45 LOAD_FAST 0 (myobj)
48 LOAD_ATTR 3 (x)
anti-attribute, remove above byte code
51 BUILD_TUPLE 4
54 RETURN_VALUE

You might want to do the same for LOAD_GLOBAL/STORE_GLOBAL, and
STORE_DEREF/LOAD_DEREF, I don't know. But it wouldn't be a big deal
to get a hack working. Thorough testing is another matter,
not to mention justifying it ;-)

Regards,
Bengt Richter
Sep 22 '05 #14
ago wrote:
Is it possible to have a default value associated python objects? I.e.
to flag an attribute in such a way that the assignment operator for the
object returns the default attribute instead of the object itself, but
calls to other object attributes are properly resolved? (I don't think
so, but I am not sure)


Python is not Visual Basic.

In Visual Basic, objects could have a default property which was set when
the object variable was assigned to, but that was only possible because
object variables had to be set with "Set", not "Let".

Reinhold
Sep 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Steven Bethard | last post by:
In the "empty classes as c structs?" thread, we've been talking in some detail about my proposed "generic objects" PEP. Based on a number of suggestions, I'm thinking more and more that instead of...
6
by: Johnny Klunk | last post by:
Wondering if someone can give me a hand with something that I'm sure is really easy - but damned if I know what I'm doing wrong. I'm trying to read the contents of a database into an ASP...
21
by: Jason Heyes | last post by:
I want to allow objects of my class to be read from an input stream. I am having trouble with the implementation. Here are the different approaches I have tried: // Version 1.0 - Default...
1
by: Bo Xu | last post by:
Object of Combination By Bo Xu Introduction A combination of n things, taken s at a time, often referred as an s-combination out of n, is a way to select a subset of size s from a given set of...
0
by: Joe Sullivan | last post by:
I am working on some VB dot net classes and am inheriting from a class that has a method that returns a general object. My problem is, of course, is when i want to return an integer using this...
8
by: Oenone | last post by:
Is it possible to create an object which can have methods and properties, but which can also be treated as a string? I'm trying to create a wrapper around the IIS Request.Form object which...
11
by: Andrus | last post by:
I'm implementing entity object which should populate its properties from database when property is first referenced. In RDL reports I use object properties like MyObject.MyProperty MyObject...
4
by: Jess | last post by:
Hello, I tried several books to find out the details of object initialization. Unfortunately, I'm still confused by two specific concepts, namely default-initialization and...
7
by: Andy B | last post by:
I have an instance of an object that needs to be accessed by all members of a page like page_load, button_click events and so on. Where in the codebehind would I put the creation of the object...
275
by: Astley Le Jasper | last post by:
Sorry for the numpty question ... How do you find the reference name of an object? So if i have this bob = modulename.objectname() how do i find that the name is 'bob'
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.