[Python-Dev] new property factory arguments
john coppola
john_coppola_r_s@yahoo.com
Mon, 18 Feb 2002 00:41:06 -0800 (PST)
--0-1827853335-1014021666=:25719
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hello python developers. After discussions with Fred
about defining how property objects are created, I
decided to give it a whirl myself. After about minute
of piddling, I came up with something I thought would
be a hack but is quite interesting.
Ultimately, this is what I came up with.
class Foo(object):
def __get__(self, container):
print "this is get"
print "self:", type(self)
print "container:", type(container)
print
def __set__(self, container, value):
print "this is set"
print "self:", type(self)
print "container:", type(container)
print "value:", value
print
def __del__(self, container):
print "this is del"
print "self:", type(self)
print "container:", type(container)
print
class Spam(object):
x=property(Foo())
I feel this has the benefit of encapsulating the x
property from the Spam object. If coupling is needed,
then access to Spam can be obtained via container.
This was the interesting hack I was talking about. I
first tried it without container and got an error, but
then I decided to see what that second argument was
like hummm, interesting and I liked it.
What's really cool is that Foo can be used by a
completely separate class. Perhaps Foo is a singleton
for a DB connection. A single connection could be
created in __new__, and other attribute details
created in __init__. So class Spam is decoupled from
what is going on in Foo. Whereas the former syntax,
this was not possible.
I've attached a descrobject.diff file to this email as
well as testprop.py. (I've never tried sending an
attachment to python-dev, I hope it works.)
Enjoy,
John Coppola
__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com
--0-1827853335-1014021666=:25719
Content-Type: text/plain; name="descrobject.diff"
Content-Description: descrobject.diff
Content-Disposition: inline; filename="descrobject.diff"
*** PythonOrig/Python-2.2/Objects/descrobject.c Sat Dec 15 00:00:30 2001
--- PythonDev/Python-2.2/Objects/descrobject.c Sun Feb 17 21:52:55 2002
***************
*** 1003,1024 ****
}
static int
! property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
! PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
! static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
! propertyobject *gs = (propertyobject *)self;
!
! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
! kwlist, &get, &set, &del, &doc))
! return -1;
!
! if (get == Py_None)
! get = NULL;
! if (set == Py_None)
! set = NULL;
! if (del == Py_None)
! del = NULL;
Py_XINCREF(get);
Py_XINCREF(set);
--- 1003,1023 ----
}
static int
! property_init(PyObject *self, PyObject *args, PyObject *kw)
{
! PyObject *get=NULL, *set=NULL, *del=NULL, *doc=NULL, *arg=NULL;
! static char *kwlist[] = {"object", 0};
! propertyobject *gs = (propertyobject *)self;
! if (!PyArg_ParseTupleAndKeywords(args,kw,"|O:property",kwlist,&arg))
! return -1;
!
! get = PyObject_GetAttrString(arg,"__get__");
! set = PyObject_GetAttrString(arg,"__set__");
! del = PyObject_GetAttrString(arg,"__del__");
! doc = PyObject_GetAttrString(arg,"__doc__");
! if (get == Py_None) get = NULL;
! if (set == Py_None) set = NULL;
! if (del == Py_None) del = NULL;
Py_XINCREF(get);
Py_XINCREF(set);
***************
*** 1034,1049 ****
}
static char property_doc[] =
! "property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n"
"\n"
! "fget is a function to be used for getting an attribute value, and likewise\n"
! "fset is a function for setting, and fdel a function for del'ing, an\n"
! "attribute. Typical use is to define a managed attribute x:\n"
"class C(object):\n"
! " def getx(self): return self.__x\n"
! " def setx(self, value): self.__x = value\n"
! " def delx(self): del self.__x\n"
! " x = property(getx, setx, delx, \"I'm the 'x' property.\")";
static int
property_traverse(PyObject *self, visitproc visit, void *arg)
--- 1033,1050 ----
}
static char property_doc[] =
! "property(object) -> property attribute\n"
"\n"
! "__get__ is a function to be used for getting an attribute value, and\n"
! "likewise __set__ is a function for setting, and __del__ a function for\n"
! "del'ing, an attribute. Typical use is to define a managed attribute x:\n"
"class C(object):\n"
! " def __get__(self, container): return self.__x\n"
! " def __set__(self, container, value): self.__x = value\n"
! " def __del__(self, container): del self.__x\n"
! "\n"
! "class D(object):\n"
! " x = property(object=C(), \"I'm the 'x' property.\")";
static int
property_traverse(PyObject *self, visitproc visit, void *arg)
--0-1827853335-1014021666=:25719
Content-Type: text/plain; name="TESTPROP.PY"
Content-Description: TESTPROP.PY
Content-Disposition: inline; filename="TESTPROP.PY"
__doc__="""\
class Foo(object):
def __get__(self, container):
print "this is get"
print "self:", type(self)
print "container:", type(container)
print
def __set__(self, container, value):
print "this is set"
print "self:", type(self)
print "container:", type(container)
print "value:", value
print
def __del__(self, container):
print "this is del"
print "self:", type(self)
print "container:", type(container)
print
__doc__ = "this is doc"
"""
exec __doc__
class Spam(object):
x=property(Foo())
print __doc__
a=Spam()
a.x=5
print "getting:", a.x
del a.x
--0-1827853335-1014021666=:25719--