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

too dynamic - how to avoid?

mic
I've spent last hour trying to debug my code, when I found out that instead
of executing object's method I accidentaly overridden it with variable (see
below example). My stupid! But as the system becomes more complex, I begun
to wonder how to avoid such situations in the future. Does anybody have some
experiences about that?

Simple example:

class test:
def a(self, value):
print value
t = test()
t.a('my test') <= returns obviously 'my test'
t.a = 'my test' <= creates object's attribute a, so I'm loosing my method

Regards,

Michal
Jul 18 '05 #1
5 1568
mic wrote:
I've spent last hour trying to debug my code, when I found out that
instead of executing object's method I accidentaly overridden it with
variable (see below example). My stupid! But as the system becomes more
complex, I begun to wonder how to avoid such situations in the future.
Does anybody have some experiences about that?
Yes, and the experience is: it's not a problem in practice. Still,
if you disagree, Python gives you the tools to protect yourself -- read
on.

Simple example:

class test:
def a(self, value):
print value
t = test()
t.a('my test') <= returns obviously 'my test'
t.a = 'my test' <= creates object's attribute a, so I'm loosing my method


First of all, be sure to make your classes newstyle, e.g.
class test(object):
otherwise, by default, you get oldstyle classes, where compatibility
constraints mean most important new features just can't work right.

Now, limiting discussion to newstyle classes only:

in a class's dictionary there are two kinds of descriptors --
somewhat arbitrarily names 'data' and 'non-data' kinds of descriptors.

The 'non-data' kind, used for example for methods, are SPECIFICALLY
designed to be overridable per-instance. The 'data' kind aren't.

(Names are rather artificial; the real distinction is whether a
__set__ method is present in the descriptor -- if yes, it's data,
otherwise it's non-data -- calling it "setting-intercept" might
be clearer than calling it 'data'...!). Check it out...:

class c(object):
def a(self): pass
b = property(a)

descriptor 'a' is non-data, so it can be overridden in instances;
descriptor 'b' is data, so it cannot. E.g.:
x=c()
x.a=23
x.b=23 Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: can't set attribute


The 'property' type of descriptors isn't quite suitable for what
you want, of course, because even just ACCESSING x.b makes a CALL
to x.a. Rather, you want a new and different "nonrebindablemethod"
type of descriptor whose __get__ is just like the function, while
its __set__ raises the exception. So, make such a type:

class norebind(object):
def __init__(self, func): self.func = func
def __get__(self, *args): return self.func.__get__(*args)
def __set__(self, *args): raise TypeError

class c(object):
def a(self): pass
b = norebind(a)

There -- now, after x=c(), attempts to rebind x.b will raise a
TypeError, as you apparently wish. Note that you can code the
class as:

class c(object):
def a(self): pass
a = norebind(a)

so that there's no x.b -- just a non-rebindable x.a.
You won't need it in practice, but it's still a cool hack:-).

Alex

Jul 18 '05 #2
"mic" <al*****@onet.pl> writes:
I've spent last hour trying to debug my code, when I found out that instead
of executing object's method I accidentaly overridden it with variable (see
below example). My stupid! But as the system becomes more complex, I begun
to wonder how to avoid such situations in the future. Does anybody have some
experiences about that?


- use of decent naming schemes presumably helps (and if your class gets so big
that you can't remember what are attributes and what are methods refactoring
would probably be a good idea)

- if that's not enough you can always do something like override __setattr__,
to check that you don't overwrite instance methods, e.g. (UNTESTED):

import types
class bar:
...
def __setattr__(self, attr, value):
if isinstance(getattr(self, attr, None), types.MethodType):
raise RuntimeError("Trying to overwrite method %s" % attr)
else setattr(self, attr, value)
- if you need this often, you could write a function or metaclass to avoid
duplicating the above in all classes where you feel you need it.
'as
Jul 18 '05 #3
"mic" <al*****@onet.pl> wrote:
I've spent last hour trying to debug my code, when I found out that instead
of executing object's method I accidentaly overridden it with variable (see
below example). My stupid! But as the system becomes more complex, I begun
to wonder how to avoid such situations in the future. Does anybody have some
experiences about that?

Simple example:

class test:
def a(self, value):
print value
t = test()
t.a('my test') <= returns obviously 'my test'
t.a = 'my test' <= creates object's attribute a, so I'm loosing my method


From this I can't discern whether you're asking a simple question or
want some sophisticated, nifty programming advice. I'm assuming you
just want some help using the interpreter and the overall programming
environment.

If something -whatever- is not quite as expected it's very important
to read the traceback (if there is one) from the interpreter output,
for example in this case trying to call t.a('my test') after t.a has
been bound to a string will result in some complaint from the
interpreter that type 'str' has no call method. It's also very a good
idea to include the traceback in usenet posts since that makes it
possible to receive more specific comments.

Another thing is that it's very handy to use the interactive
interpreter to test pieces of code that behave in unexpected ways.
Just try it out and check the output of your functions. It's not like
indexing an array out of bounds will make your complete system crash
or make it instable, Python is reasonably well defended against simple
mistakes.

The dir command is handy too, for example dir(t.a) will give some info
about what the interpreter thinks t.a is. Next, sprinkling your code
with print statements -turning it into a poor mans debugger system-
works very well for most of the mistakes of this calibre.

Please note that given the dynamic nature of Python the above code
snippet might be exactly what you want and there's no way for the
interpreter yet to do what you intend rather than what you code ;-)

Then there's the debugger inside Idle, but the strategies above are
sufficient in most cases, so that -at least in my case- it's almost
never necessary to use it. I mostly use Scite as an editor and have
pychecker* a single keypress away, but I only use it to doublecheck my
code after it runs as expected.

HTH,

Anton

* http://pychecker.sourceforge.net/

Jul 18 '05 #4
On Thu, 02 Oct 2003 11:56:49 +0200, mic wrote:
My stupid! But as the system becomes more complex, I begun
to wonder how to avoid such situations in the future. Does anybody have some
experiences about that?


1) Don't do it.
2) You can use a naming convention
a) Methods have verbs, variables don't: set_temperature, temperature
b) Prefix members with warts: x.temperature() x._temperature or
x.its_temperature
c) Your choice here
3) See #1, above

Pychecker doesn't seem to pick this up. I don't know about pylint.
I guess it might be something possible if you are talking methods
and attributes.

Tim
Jul 18 '05 #5
"mic" <al*****@onet.pl> writes:
I've spent last hour trying to debug my code, when I found out that instead
of executing object's method I accidentaly overridden it with variable (see
below example). My stupid! But as the system becomes more complex, I begun
to wonder how to avoid such situations in the future. Does anybody have some
experiences about that?


I don't understand how that could cause a problem. Why didn't you
immediately get a traceback with a message something like 'a is not
callable'?
John
Jul 18 '05 #6

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

Similar topics

1
by: foldface | last post by:
Hi I'm working with a web site where 99% of the content is dynamic and words can be of any size, e.g. thiswouldbeavalidword. At the moment everything is done using inner tables, I want to move to...
14
by: Spare Change | last post by:
I am told that I can have a dynamic or static string array. So if I declare string dynamic; How do I add elements to dynamic and resize it ?
4
by: Leslaw Bieniasz | last post by:
Cracow, 20.10.2004 Hello, As far as I understand, the generic programming basically consists in using templates for achieving a static polymorphism of the various code fragments, and their...
6
by: chris | last post by:
Hi all, I need to know, what is the difference between dynamic memory allocation, and stack allocation ? 1. If I have a class named DestinationAddress, when should I use dynamic memory...
7
by: Ford Desperado | last post by:
there is an application which issues a lot of simple dynamic queries against an Oracle database. If CURSOR_SHARING is set to FORCE, Oracle treats dynamic queries as static ones, for instance...
3
by: Leo J. Hart IV | last post by:
OK, here's another question for the experts: I am building a multi-step (3 steps actually) form using a panel for each step and hiding/displaying the appropriate panel/panels depending on which...
1
by: Luis Ferrao | last post by:
Hi, To understand the problem, a small description of the situation should be provided: I have a Field Control that is made of a one row table with three columns. The table width is 100%, the...
11
by: toton | last post by:
Hi, I have little confusion about static memory allocation & dynamic allocation for a cluss member. I have class like class Bar{ public: explicit Bar(){ cout<<"bar default"<<endl; }
9
by: Tarscher | last post by:
hi all, I have this seemingly simple problem. I have lost a lot of time on it though. When a user selects a value from a dropdownlist (static control) a dynamic control is generated. I have...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
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,...

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.