473,804 Members | 1,971 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why property works only for objects?

Hi,

Code below shows that property() works only if you use it within a class.

------------------------------------------------
class A(object):
pass

a = A()
a.y = 7

def method_get(self ):
return self.y

a.x = property(method _get)
print a.x # => <property object at 0xb7dc1c84>

A.x = property(method _get)
print a.x # => 7
------------------------------------------------

Is there any method of making descriptors on per-object basis? I would
like to customize x access in different objects of class A. Is this
possible and how?

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
Mar 10 '06 #1
25 1764
Michal Kwiatkowski wrote:
Code below shows that property() works only if you use it within a class.
Yes, descriptors are only applied at the class level (that is, only
class objects call the __get__ methods).
Is there any method of making descriptors on per-object basis?


I'm still not convinced that you actually want to, but you can write
your own descriptor to dispatch to the instance object (instead of the
type):
class InstancePropert y(object): .... def __init__(self, func_name):
.... self.func_name = func_name
.... def __get__(self, obj, type=None):
.... if obj is None:
.... return self
.... return getattr(obj, self.func_name) (obj)
.... class C(object): .... x = InstancePropert y('_x')
.... c = C()
c.x Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
File "<interacti ve input>", line 7, in __get__
AttributeError: 'C' object has no attribute '_x' def getx(self): .... return 42
.... c._x = getx
c.x

42
STeVe
Mar 10 '06 #2
Steven Bethard napisa³(a):
Is there any method of making descriptors on per-object basis?


I'm still not convinced that you actually want to, but you can write
your own descriptor to dispatch to the instance object (instead of the
type):


Ok, this works for attributes I know a name of at class definition. What
about other situations? I could possibly want to have different sets of
attributes for instances of a class. Is it still possible to do? I don't
also like current solution, as it wraps things around, creating another
attribute ('_x') in the process. Aren't there any cleaner solutions?

The problem is I have an instance of a given class (say BaseClass) and I
want it to implement some attribute accesses as method calls. I'm not a
creator of this object, so changing definition of BaseClass or
subclassing it is not an option. Code below doesn't work, but shows my
intention:

# obj is instance of BaseClass
def get_x(self):
# ...
def set_x(self, value):
# ...
obj.x = property(get_x, set_x)

Changing __setattr__/__getattr__ of an object also doesn't work for the
same reason: dictionary lookup is made only in class attributes,
ommiting object attributes. It's confusing, because writting obj.x and
obj.__getattrib ute__('x') gives a different results. There also seems
not to be any clear way to define methods for objects. Something like:

class C(object):
pass

def method(self):
return self.x

c = c.x
c.method = method
c.method() # => AttributeError

So another question arise. Is it possible to make function a method (so
it will receive calling object as first argument)?

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
Mar 10 '06 #3
Michal Kwiatkowski <ru**@no.spam > wrote:
...
The problem is I have an instance of a given class (say BaseClass) and I
want it to implement some attribute accesses as method calls. I'm not a
creator of this object, so changing definition of BaseClass or
subclassing it is not an option.
Wrong! Of _course_ it's an option -- why do you think it matters at all
whether you're the creator of this object?!
Code below doesn't work, but shows my
intention:

# obj is instance of BaseClass
def get_x(self):
# ...
def set_x(self, value):
# ...
obj.x = property(get_x, set_x)


def insert_property (obj, name, getter, setter):
class sub(obj.__class __): pass
setattr(sub, name, property(getter , setter))
obj.__class__ = sub

See? Of COURSE you can subclass -- not hard at all, really.
Alex
Mar 10 '06 #4
Michal Kwiatkowski <ru**@no.spam > wrote:
So another question arise. Is it possible to make function a method (so
it will receive calling object as first argument)?


Sure, impor types then call types.MethodTyp e:

f = types.MethodTyp e(f, obj, someclass)

(f.__get__ is also fine for Python-coded functions) -- make sure that
someclass is obj's class or some ancestor of it, of course.
Alex
Mar 10 '06 #5
Alex Martelli napisa³(a):
Wrong! Of _course_ it's an option -- why do you think it matters at all
whether you're the creator of this object?!


Statically typed languages background. Sorry. ;)
Code below doesn't work, but shows my
intention:

# obj is instance of BaseClass
def get_x(self):
# ...
def set_x(self, value):
# ...
obj.x = property(get_x, set_x)


def insert_property (obj, name, getter, setter):
class sub(obj.__class __): pass
setattr(sub, name, property(getter , setter))
obj.__class__ = sub

See? Of COURSE you can subclass -- not hard at all, really.


Let me understand it clearly. If I change __class__ of an object,
existing attributes (so methods as well) of an object are still
accessible the same way and don't change its values. Only resolution of
attributes/methods not found in object is changed, as it uses new
version of __class__ to lookup names. Is this right?

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
Mar 10 '06 #6
Alex Martelli napisa³(a):
So another question arise. Is it possible to make function a method (so
it will receive calling object as first argument)?


Sure, impor types then call types.MethodTyp e:

f = types.MethodTyp e(f, obj, someclass)

(f.__get__ is also fine for Python-coded functions) -- make sure that
someclass is obj's class or some ancestor of it, of course.


I wasn't aware of types module. Thanks for your reply.

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
Mar 10 '06 #7
Michal Kwiatkowski a écrit :
Steven Bethard napisa³(a):
Is there any method of making descriptors on per-object basis?
I'm still not convinced that you actually want to, but you can write
your own descriptor to dispatch to the instance object (instead of the
type):

Ok, this works for attributes I know a name of at class definition. What
about other situations? I could possibly want to have different sets of
attributes for instances of a class.


Then you want a different class for each different set of attributes.
Is it still possible to do? I don't
also like current solution, as it wraps things around, creating another
attribute ('_x') in the process. Aren't there any cleaner solutions?

The problem is I have an instance of a given class (say BaseClass) and I
want it to implement some attribute accesses as method calls. I'm not a
creator of this object, so changing definition of BaseClass or
subclassing it is not an option.
What you want is delegation. Which is pretty easy with Python, look at
__getattr__ and __setattr__.
Code below doesn't work, but shows my
intention:

# obj is instance of BaseClass
def get_x(self):
# ...
def set_x(self, value):
# ...
obj.x = property(get_x, set_x)
class ObjWrapper(obje ct):
def __init__(self, obj):
self.obj = obj

# special case x
def _get_x(self):
return self.obj.x

def _set_x(self, value):
self.obj.x = value

x = property(fget=_ get_x, fset=_set_x)

# default lookup, directly delegate to obj
def __getattr__(sel f, name):
return getattr(self.ob j, name)

def __setattr__(sel f, name, value):
# this one is a bit more tricky
# and I don't remember it right now,
# but it's in the fine manual anyway

obj = ObjWrapper(obj)
obj.x # calls ObjWrapper._get _x()

Changing __setattr__/__getattr__ of an object also doesn't work for the
same reason: dictionary lookup is made only in class attributes,
ommiting object attributes. It's confusing, because writting obj.x and
obj.__getattrib ute__('x') gives a different results. There also seems
not to be any clear way to define methods for objects. Something like:

class C(object):
pass

def method(self):
return self.x

c = c.x
c.method = method
c.method() # => AttributeError
import types
c.method = types.MethodTyp e(method, c, c.__class__)
So another question arise. Is it possible to make function a method (so
it will receive calling object as first argument)?


Yeps, just wrap it in a Method object (cf above)

Mar 10 '06 #8
Michal Kwiatkowski a écrit :
Alex Martelli napisa³(a):
Wrong! Of _course_ it's an option -- why do you think it matters at all
whether you're the creator of this object?!

(snip)

def insert_property (obj, name, getter, setter):
class sub(obj.__class __): pass
setattr(sub, name, property(getter , setter))
obj.__class__ = sub

See? Of COURSE you can subclass -- not hard at all, really.

Let me understand it clearly. If I change __class__ of an object,
existing attributes (so methods as well)
of an object are still
accessible the same way and don't change its values. Only resolution of
attributes/methods not found in object is changed, as it uses new
version of __class__ to lookup names. Is this right?


Attributes, yes. Not methods. Methods are looked up in the class. But in
the example above (brillant, as usual), Alex dynamically creates a
subclass of obj.__class__, so inheritence takes care of methods lookup.

mk

Mar 11 '06 #9
Bruno Desthuilliers napisa³(a):
Let me understand it clearly. If I change __class__ of an object,
existing attributes (so methods as well) of an object are still
accessible the same way and don't change its values. Only resolution of
attributes/methods not found in object is changed, as it uses new
version of __class__ to lookup names. Is this right?


Attributes, yes. Not methods. Methods are looked up in the class.


My experience shows exactly the opposite. Any attribute/method you try
to access is first looked up in object dictionary, then inside class
definition.

import types

class C(object):
def f(self):
print "old method f()"

obj = C()

def f(self):
print "new method f()"

obj.f = types.MethodTyp e(f, C)

obj.f() # => "new method f()"

Since that works, intuitively for me would be to assign object's
descriptors like that:

obj.x = property(types. MethodType(lamb da self: 42, C))

But I just get a property object. So, it seems descriptors have little
bit of magic, as they don't work identically for classes and objects.

The same goes for special methods and attributes (written as __*__). So
I cannot change __getattr__/__setattr__/__metaclass__ or any other
attribute that starts with __ for a single object. It's not so bad
except for situations were class of an object defines its own
__getattribute_ _ method, which takes control of an object from us. To
get/set any attribute of an object we must use object type methods:

class C(object):
def __getattribute_ _(self, name):
return 42

obj = C()

obj.a = 5

print obj.a # => 42
print object.__getatt ribute__(obj, 'a') # => 5

I gets even more strange when you try to modify, say __len__ or
__repr__. Docstring for object.__repr__ says:
"x.__repr__ () <==> repr(x)" which doesn't seem to be always true:

class C(object):
def __repr__(self):
return "class repr"

obj = C()
obj.__repr__ = types.MethodTyp e(lambda self: "instance repr", C)

print repr(obj) # => class repr
print obj.__repr__() # => instance repr

Maybe the manual should say "x.__class__.__ repr__() <==> repr(x)" instead?

I'm trying to understand attributes lookups made by Python, having
properties and special methods in mind. So far I've come up with kind of
reasoning I've coded below. I would appreciate any comments and
suggestions.

def lookup_name(obj , name):
get = lambda obj, name: object.__getatt ribute__(obj, name)
has = lambda obj, name: name in get(obj, '__dict__')

# assume C is a new style class
C = get(obj, '__class__')

# 1) use class' __getattribute_ _ method
try:
if has(C, '__getattribute __'):
return get(C, '__getattribute __')(obj, name)
except AttributeError: pass

# 2) lookup in object's dictionary
try:
if has(obj, name):
return get(obj, name)
except AttributeError: pass

# 3) lookup in classes
for c in obj.__class__.m ro():
try:
if has(c, name):
desc = get(c, name)
# 3a) handle descriptors
try:
return get(desc, '__get__')(obj)
except: pass
# 3b) no descriptors -> use value
return desc
except AttributeError: pass

raise AttributeError, "Not found!"

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
Mar 11 '06 #10

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

Similar topics

2
1954
by: Aaron | last post by:
Hi, I've seen javascript code where a constructor function is passed an argument "document", and inside the function itself the assignment "this.document = document;" is made. This is the code (or the part necessary for the example): function ToggleButton(document) { ToggleButton.images = new Array(4); for(i=0;i<4;i++) { ToggleButton.images = new
16
25424
by: sneill | last post by:
How is it possible to take the value of a variable (in this case, MODE_CREATE, MODE_UPDATE, etc) and use that as an object property name? In the following example I want 'oIcon' object to have the properties: mode1, mode2, and mode3. This seems simple but I can't quite figure it out... Any ideas anyone?
3
2556
by: Mark Jones | last post by:
I am quite new to ASP and .Net development and I am building a web-based multiple choice exam application. The web page displays the questions using a Repeater control and the answers are nested within the Repeater as RadioButtonLists. Simple enough I think. My data consists of a Question table and an Answer table. The Question table has a QuestionID and a Question field. The Answer table has a AnswerID field, an Answer field and a...
15
1929
by: Sam Kong | last post by:
Hello! I got recently intrigued with JavaScript's prototype-based object-orientation. However, I still don't understand the mechanism clearly. What's the difference between the following two? (1)
1
1838
by: David Veeneman | last post by:
This posting is for the Google crawler and requires no response. I have created a multi-level object hierarchy, in which the root object needs to be notified whenever any property of any object in the collection changes. I wanted to enable this communication without passing child objects references to their parents. Those references increase the internal coupling of an object hierarchy and should be avoided where possible. Here is how...
2
2211
by: garyusenet | last post by:
I could do with something similiar, can you tell me if you think this would work for me, and if there's any advantage in working with controls this way than how I currently am. At the moment i'm using the treenodes and each treenode needs a unique entry into my rich text box. After sitting at home with MSDN i've managed to get this functionality by storing a RTF string in the tag property of the treenode. On every 'before update' of the...
4
12855
by: NASAdude | last post by:
I'm working on distributing a database using VS Tools for Office, and am having trouble with linked images on forms/reports. The image objects have a default path\file set on the .Picture property, which becomes invalid when the user installs the database (ie: c:\devpath\ becomes c:\program files\mydbapp, but the .Picture property still points to c:\devpath\) The problem is that I don't *know* what installation path the user will select,...
10
2113
by: Franky | last post by:
I think I misread a post and understood that if I do: System.Windows.Forms.Cursor.Current = Cursors.WaitCursor there is no need to reset the cursor to Default. So I made all the reset statements into comments (placed an ' in front)
4
35995
by: Steve | last post by:
I am using a property grid to display a classes properties, all is OK for single value properties but i need to display a list of strings for the user to select from and update the property value based on the selection. A Drop down list in the property grid would be ideal. For instance - like the StartPosition property of a form in the IDE. I think this would be a simple and often used procedure but i have not been able to locate an...
0
10595
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10343
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10335
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7633
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6862
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5529
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5668
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3831
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3001
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.