473,323 Members | 1,560 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,323 software developers and data experts.

Handling Property and internal ('__') attribute inheritance andcreation

Hi,

I've been thinking in circles about these aspects of Pythonic design
and I'm curious what everyone else is doing and thinks. There are 3
issues here:
1) 'Declaring' attributes - I always felt it was good code practice to
declare attributes in a section of the class namespace. I set anything
that is constant but anything variable is set again in __init__():

Class A(object):
name = "a name"
type = "a typee"
childobject = None

def __init__(self, obj):
self.childobject = object

This makes it easy to remember and figure out what is in the class.
Granted there is nothing to enforce this, but that is why I called it
'code practice'. Do you agree or is this just extra work?
2) Internal attributes (starting with 2x'_') aren't inherited. Do you
just switch to a single '_' when you want an "internal" attribute
inherited? These are attributes I want the classes to use but not the
user of these classes. Of course, like anything else in Python, these
aren't really private. It is just a convention, right? (The example
for #3 shows this.)
3) It isn't possible to override a piece of a Property Descriptor. To
get around this, I define the necessary functions in the class but I
define the descriptor in the __new__() method so the inherting class
can override the methods. Am I overlooking some basic design principle
here? This seems like a lot of work for a simple behavior. Example:

class Base(object):
def __new__(cls):
setattr(cls,
"state",
property(fget = cls._Get_state,
fset = cls._Set_state,
fdel = None,
doc = cls._doc_state))

obj = super(Base, cls).__new__(cls)
return obj

state = None # Set in __new__()
_state = True
_doc_state = "The state of this object"
def _Get_state(self): return self._state
def _Set_state(self, value): self._state = value

class Child(Base):
def _Get_state(self):
# Do some work before getting the state.
print "Getting the state using the child's method"
return self._state

print Child().state

Please share your thoughts,

- Rafe
Aug 15 '08 #1
5 1455
Bruno Desthuilliers wrote:
How often do you really need to override a property ? (hint : as far as
I'm concerned, it never happened so far). Now you have two solutions :
either redefine the whole property in the derived class, or, if you
really intend your property to be overriden, provide a "template method"
hook.
In Python 2.6 and 3.0 you can override the setter, getter or deleter of
a property in a subclass. You may be able to find a pure Python
implementation written by Guido. My C implementation in the core works
almost the same.

Christian

Aug 15 '08 #2
On Fri, 15 Aug 2008 20:02:36 +0200, Rafe <ra*******@gmail.comwrote:
[snip]
1) 'Declaring' attributes - I always felt it was good code practice to
declare attributes in a section of the class namespace. I set anything
that is constant but anything variable is set again in __init__():

Class A(object):
name = "a name"
type = "a typee"
childobject = None

def __init__(self, obj):
self.childobject = object

This makes it easy to remember and figure out what is in the class.
Granted there is nothing to enforce this, but that is why I called it
'code practice'. Do you agree or is this just extra work?
To add to what others have already said, it is not only 'just extra work',
it is also quite dangerous. See:

class A(object):
children = []

Now *all* A instances share the *same* list, as it was defined as a class
attribute. If you ever forget to set it to something else in __init__,
you're in for big surprises.

What I'm doing is set all instance attributes right at the beginning of
the __init__ with a huge comment before them, like:

class A(object):
def __init__(self):
## INSTANCE ATTRIBUTES:
## --------------------
self.children = []

This way, you still can 'figure out what is in the class' quite quickly,
without the drawbacks of declaraing class attributes.

HTH
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
Aug 19 '08 #3
Eric Brunel wrote:
To add to what others have already said, it is not only 'just extra
work', it is also quite dangerous. See:

class A(object):
children = []
the OP is aware of that, of course:
I set anything that is constant but anything variable is set again in
__init__()
as long as if you're aware of the issues involved (which you should be
if you're using Python professionally), using class-level attributes is
a perfectly valid Python style.

</F>

Aug 19 '08 #4
Fredrik Lundh a écrit :
Eric Brunel wrote:
>To add to what others have already said, it is not only 'just extra
work', it is also quite dangerous. See:

class A(object):
children = []

the OP is aware of that, of course:
I set anything that is constant but anything variable is set again in
__init__()

as long as if you're aware of the issues involved (which you should be
if you're using Python professionally), using class-level attributes is
a perfectly valid Python style.
Using class attributes is perfectly valid Python style, indeed. But in
this case - ie: using class attributes as a pseudo-declaration of
instance attributes -, I would not call this good style : it's a waste
of time, a violation of DRY, and a potential source of confusion for the
class's users / maintainers.
Aug 19 '08 #5
On Aug 16, 1:22 am, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
Rafea écrit :
Hi,
I've been thinking in circles about these aspects of Pythonic design
and I'm curious what everyone else is doing and thinks. There are 3
issues here:
1) 'Declaring' attributes

There's nothing like "declaration" of variables/attributes/whatever in
Python.
- I always felt it was good code practice to
declare attributes in a section of the class namespace. I set anything
that is constant but anything variable is set again in __init__():
Class A(object):
name = "a name"
type = "a typee"
childobject = None
def __init__(self, obj):
self.childobject = object
This makes it easy to remember and figure out what is in the class.
Granted there is nothing to enforce this, but that is why I called it
'code practice'. Do you agree or is this just extra work?

It's not only extra work, it's mostly a WTF. You create class attributes
for no other reasons than to mimic some other mainstream languages. If I
was to maintain such code, I'd loose valuable time wondering where these
class attributes are used.
2) Internal attributes (starting with 2x'_') aren't inherited.

Yes they are. But you need to manually mangle them when trying to access
them from a child class method. FWIW, that *is* the point of
__name_mangling : making sure these attributes won't be accidentally
overwritten in a child class.
Do you
just switch to a single '_' when you want an "internal" attribute
inherited? These are attributes I want the classes to use but not the
user of these classes. Of course, like anything else in Python, these
aren't really private. It is just a convention, right? (The example
for #3 shows this.)

Yes. The (*very* strong) convention is that
_names_with_simple_leading_underscore denote implementation attributes.
3) It isn't possible to override a piece of a Property Descriptor. To
get around this, I define the necessary functions in the class but I
define the descriptor in the __new__() method so the inherting class
can override the methods. Am I overlooking some basic design principle
here? This seems like a lot of work for a simple behavior. Example:
class Base(object):
def __new__(cls):
setattr(cls,
"state",
property(fget = cls._Get_state,
fset = cls._Set_state,
fdel = None,
doc = cls._doc_state))
obj = super(Base, cls).__new__(cls)
return obj
state = None # Set in __new__()
_state = True
_doc_state = "The state of this object"
def _Get_state(self): return self._state
def _Set_state(self, value): self._state = value

pep08 : attribute names (including methods) should be all_lower.
class Child(Base):
def _Get_state(self):
# Do some work before getting the state.
print "Getting the state using the child's method"
return self._state
print Child().state

How often do you really need to override a property ? (hint : as far as
I'm concerned, it never happened so far). Now you have two solutions :
either redefine the whole property in the derived class, or, if you
really intend your property to be overriden, provide a "template method"
hook.

I'd say you're making things much more complicated than they need to be.

Thanks Bruno, and everyone ! These are exactly the type of hard
answers I was hoping for. I'm mostly converted but my brain still
needs a Pythonic push from time to time. Looks like have some some
clean up to perform...with confidence.

I'm interested to see the implementation of getter, etc overrides in
2.6/3.0. I have two classes that could be simplified with this. For
example, I have a class which does a lot of work and has about 5 key
properties. I want to inherit it, and just trigger an event (update
something only stored in the child) after 4 of these attributes are
finished being set. I was thinking about using a callback which is
empty in the parent or __setattr__() (but I hat using this unless I
have to, it is still troublesome to me).

- Rafe
Aug 19 '08 #6

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

Similar topics

0
by: Marcin 'Qrczak' Kowalczyk | last post by:
I made a bridge between my language Kogut <http://qrnik.knm.org.pl/~qrczak/kogut/kogut.html> and Python, which gives my language instant access to Python libraries. There is a minor annoyance in...
1
by: Skip Montanaro | last post by:
I just stumbled upon a bug in some group-written code. We have this sort of class hierarchy: class X(object): ... class A(X): def __init__(...): self.attr = 0.0
3
by: kepes.krisztian | last post by:
Hi ! I want to create a property that can use parameter(s). In Delphi I can create same thing (exm: Canvas.Pixel -> Canvas.GetPixel(self,X,Y):integer; Canvas.SetPixel(self,X,Y,Color::integer); ...
1
by: Sean W. Quinn | last post by:
Hey folks, I have a question regarding file handling, and the preservation of class structure. I have a class (and I will post snippets of code later in the post) with both primitive data...
18
by: Robin Becker | last post by:
Is there a way to override a data property in the instance? Do I need to create another class with the property changed? -- Robin Becker
5
by: Mateusz Loskot | last post by:
Hi, I'd like to ask how XML parsers should handle attributes which consists of &quot; entity as value. I know XML allows to use both: single and double quotes as attribute value terminator. That's...
7
by: Baski | last post by:
Base class: class AssetBase { string _clli; public string CLLI { get
25
by: Michal Kwiatkowski | last post by:
Hi, Code below shows that property() works only if you use it within a class. ------------------------------------------------ class A(object): pass a = A() a.y = 7
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...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.