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

Automatic Generation of Python Class Files

I was thinking of a way I could make writing Python Class Files a
little less painful. I was considering a Ptyhon script that read a
file with a list of property names and method names and then generated
a skeleton class file.

I was even thinking of automatically generating the shell for doc
strings and epydoc tags.

Is there existing scripts that do something like this? If not, I will
try to come up with something. If I'm sucessful I'll release the code
under the GPL and will report back to the list.

However, I thought I would check here first so that I don't reinvent
the wheel.

Thanks,

Scott Huey

Oct 22 '07 #1
17 2281
Sunburned Surveyor a écrit :
I was thinking of a way I could make writing Python Class Files
What's a "Python Class File" ?
a
little less painful.
If you find writing classes in Python "painful", then either you have no
experience with any mainstream language or you are doing something wrong.
I was considering a Ptyhon script that read a
file with a list of property names and method names and then generated
a skeleton class file.
Once again, there's no such thing as a "class file" in Python. A module
usually contains several (classes, functions etc) definitions. And since
there's very few boilerplate code in Python, I don't see what your
system would be good for - directly writing the code will not take much
more time than writing the "file with a list of property names and
method names".

My 2 cents...
Oct 22 '07 #2
On Mon, 22 Oct 2007 11:05:52 -0700, Sunburned Surveyor wrote:
On Oct 22, 10:26 am, "Chris Mellon" <arka...@gmail.comwrote:

You wrote: " can't think of a single reason why you would ever want to
do this,
since your "list of method and property names" would be just as
verbose as just typing the actual python code."

I don't think I understand how this would be the same amount of
typing. Consider the following example that would generate a Monster
class file from an input text file (I only did one property and method
in generated class file.):
Really a "monster class".
Contents of input text file:

[Name]
Fire Breathing Dragon

[Properties]
Strength
Scariness
Endurance

[Methods]
eatMaiden argMaiden
fightKnight argKnight

Generated Python Class File:

def class FireBreathingDragon:

def getStrength(self):
"""
Docstring goes here.

@return
@rtype
"""
return self.strength

def setStrength(self, argStrength):
"""
Docstring goes here.

@param argStrength
@ptype
"""
return self.strength

def eatMaiden(self, argMaiden):
"""
Docstring goes here.

@param argMaiden
@ptype
"""
Okay this could be written as:

class FireBreathingDragon(object):
def __init__(self, strength):
self.strength = strength
self.scariness = scariness
self.endurance = endurance

def eat_maiden(self, maiden):
pass

def fight_knight(self knight):
pass

Even with all the stuff from your input file it's shorter than your
generated class.

I left out the docs because having no docs is as valuable as your stubs if
not even better. This way you at least see that there is no real docs and
tools like `pylint` can point out the missing docs.

There are editors with good template support for the small amount of
boilerplate that's left.

Just in case you want to defend the default getters and setters: read up
on properties, i.e. the `property()` function, and the discussions in this
group about Python not being Java.

Ciao,
Marc 'BlackJack' Rintsch
Oct 22 '07 #3
Sunburned Surveyor wrote:
Contents of input text file:

[Name]
Fire Breathing Dragon

[Properties]
Strength
Scariness
Endurance

[Methods]
eatMaiden argMaiden
fightKnight argKnight

Generated Python Class File:

def class FireBreathingDragon:

def getStrength(self):
"""
Docstring goes here.

@return
@rtype
"""
return self.strength

def setStrength(self, argStrength):
"""
Docstring goes here.

@param argStrength
@ptype
"""
return self.strength

def eatMaiden(self, argMaiden):
"""
Docstring goes here.

@param argMaiden
@ptype
"""
This should instead generate::

# Inherit from object. There's no reason to create old-style classes.
class FireBreathingDragon(object):

# Python is not Java. You don't need getters and setters.
# Use public attributes. If you ever decide later that you
# need different attributes, you can always use property()
# to make your getters and setters look like public attributes
def __init__(self, stregth, scariness, endurance):
self.strength = strength
self.scariness = scariness
self.endurance = endurance
STeVe
Oct 22 '07 #4
You wrote: " can't think of a single reason why you would ever want to
do this,
since your "list of method and property names" would be just as
verbose as just typing the actual python code."

I don't think I understand how this would be the same amount of
typing. Consider the following example that would generate a Monster
class file from an input text file (I only did one property and method
in generated class file.):

Contents of input text file:

[Name]
Fire Breathing Dragon

[Properties]
Strength
Scariness
Endurance

[Methods]
eatMaiden argMaiden
fightKnight argKnight
Others have already given you reasons why that is a bad idea. Another
one is this: how do you deal with changes to your generated classfile?
It's complicated to ensure that you don't override modified code with
generated.

Diez
Oct 22 '07 #5
On Oct 22, 11:43 am, Steven Bethard <steven.beth...@gmail.comwrote:
Sunburned Surveyor wrote:
Contents of input text file:
[Name]
Fire Breathing Dragon
[Properties]
Strength
Scariness
Endurance
[Methods]
eatMaiden argMaiden
fightKnight argKnight
Generated Python Class File:
def class FireBreathingDragon:
def getStrength(self):
"""
Docstring goes here.
@return
@rtype
"""
return self.strength
def setStrength(self, argStrength):
"""
Docstring goes here.
@param argStrength
@ptype
"""
return self.strength
def eatMaiden(self, argMaiden):
"""
Docstring goes here.
@param argMaiden
@ptype
"""

This should instead generate::

# Inherit from object. There's no reason to create old-style classes.
class FireBreathingDragon(object):

# Python is not Java. You don't need getters and setters.
# Use public attributes. If you ever decide later that you
# need different attributes, you can always use property()
# to make your getters and setters look like public attributes
def __init__(self, stregth, scariness, endurance):
self.strength = strength
self.scariness = scariness
self.endurance = endurance

STeVe- Hide quoted text -

- Show quoted text -
Thank you for the advice Steve. I didn't know that I should inherit
from Object. I will change my existing Python code accordingly.

Scott Huey

Oct 22 '07 #6
Sunburned Surveyor wrote:
I also intended to add statements creating properties from the getter
and setter methods. I understand that getters and setters aren't
really necessary if you aren't making a property. I just forgot to add
the property statements to my example.
You still don't want to define the getters and setters if they're just
going to set an attribute. Just use an attribute itself.

Java makes you define getters and setters because there's no way to make
method calls look like an attribute access. So in Java if you start
with a public attribute, you can never adjust the API later.

In Python, you can use property() to make method calls look like
attribute access. This could be necessary if you have an existing API
that used public attributes, but changes to your code require those
attributes to do additional calculations now.

But if you're creating a class for the first time, it should *never* use
property(). There's no need to retrofit anything.

STeVe
Oct 22 '07 #7
Steven Bethard a écrit :
(snip)
In Python, you can use property() to make method calls look like
attribute access. This could be necessary if you have an existing API
that used public attributes, but changes to your code require those
attributes to do additional calculations now.

But if you're creating a class for the first time, it should *never* use
property(). There's no need to retrofit anything.
May I kindly disagree here ?-)

Computed attributes are IMHO not only a life-saver when it comes to
refactoring. There are cases where you *really* have - by 'design' I'd
say - the semantic of a property, but know from the start you'll need
computation (for whatever reason). Then what would be the rationale for
using explicit getters/setters ?

Oct 22 '07 #8
On Oct 22, 1:23 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
Steven Bethard a écrit :
(snip)
In Python, you can use property() to make method calls look like
attribute access. This could be necessary if you have an existing API
that used public attributes, but changes to your code require those
attributes to do additional calculations now.
But if you're creating a class for the first time, it should *never* use
property(). There's no need to retrofit anything.

May I kindly disagree here ?-)

Computed attributes are IMHO not only a life-saver when it comes to
refactoring. There are cases where you *really* have - by 'design' I'd
say - the semantic of a property, but know from the start you'll need
computation (for whatever reason). Then what would be the rationale for
using explicit getters/setters ?
Bruno,

Thanks for the detailed response. I need some time to digest what you
wrote. I will read this thread again and think carefully about what
you have saaid.

Scott Huey

Oct 22 '07 #9
On Oct 22, 11:44 am, "Diez B. Roggisch" <de...@nospam.web.dewrote:
You wrote: " can't think of a single reason why you would ever want to
do this,
since your "list of method and property names" would be just as
verbose as just typing the actual python code."
I don't think I understand how this would be the same amount of
typing. Consider the following example that would generate a Monster
class file from an input text file (I only did one property and method
in generated class file.):
Contents of input text file:
[Name]
Fire Breathing Dragon
[Properties]
Strength
Scariness
Endurance
[Methods]
eatMaiden argMaiden
fightKnight argKnight

Others have already given you reasons why that is a bad idea. Another
one is this: how do you deal with changes to your generated classfile?
It's complicated to ensure that you don't override modified code with
generated.

Diez- Hide quoted text -

- Show quoted text -
Diez,

I didn't realize all of the shortcomings with my example until the
others responded. I was just trying to save myself some typing, but I
realize know the problem was my lack of understanding Python syntax.

I will consider myself schooled! :]

Scott Huey

Oct 22 '07 #10
On Mon, 22 Oct 2007 17:31:51 -0600, Steven Bethard wrote:
Bruno Desthuilliers wrote:
>Computed attributes are IMHO not only a life-saver when it comes to
refactoring. There are cases where you *really* have - by 'design' I'd
say - the semantic of a property, but know from the start you'll need
computation (for whatever reason). Then what would be the rationale for
using explicit getters/setters ?

I'd be interested to hear what these use cases are.
Stupid little example: A circle object with `radius` and `diameter`
attributes. It doesn't make sense to store both a as normal attributes
because they will eventually get out of sync. One can be implemented as a
property.

Another one is delegation of attribute access. I'm thinking of a wrapper
class around an object with an attribute, say `is_active`, and a wrapper
that has a property with the same name that returns the value of the
wrapped objects attribute.

Or lazy computation of an attribute. Breaks expectations for the first
access -- long calculation for simple attribute access -- but meets it for
every subsequent access.

Ciao,
Marc 'BlackJack' Rintsch
Oct 23 '07 #11
Marc 'BlackJack' Rintsch wrote:
On Mon, 22 Oct 2007 17:31:51 -0600, Steven Bethard wrote:
>Bruno Desthuilliers wrote:
>>Computed attributes are IMHO not only a life-saver when it comes to
refactoring. There are cases where you *really* have - by 'design' I'd
say - the semantic of a property, but know from the start you'll need
computation (for whatever reason). Then what would be the rationale for
using explicit getters/setters ?
I'd be interested to hear what these use cases are.

Stupid little example: A circle object with `radius` and `diameter`
attributes. It doesn't make sense to store both a as normal attributes
because they will eventually get out of sync. One can be implemented as a
property.
Could be. But I'd tend to define a get_diameter() method here. As a
user of your class, I'd like to know which one is doing the computation.
What if I'm using ridiculously large ints, and I care about the
multiplication?
Another one is delegation of attribute access. I'm thinking of a wrapper
class around an object with an attribute, say `is_active`, and a wrapper
that has a property with the same name that returns the value of the
wrapped objects attribute.
This is retrofitting to an API, so it already falls under the only time
I think you *should* be using property(). Although in this case, it
might be that __getattr__ is more appropriate.
Or lazy computation of an attribute. Breaks expectations for the first
access -- long calculation for simple attribute access -- but meets it for
every subsequent access.
There are descriptors better than property() at achieving this behavior.
See for example:

http://aspn.activestate.com/ASPN/Coo.../Recipe/363602

My personal experience is that every time I write stuff this way (and I
have many times), I end up re-writing it later as a method because it's
less confusing for a method to take a long time than it is for an
attribute access.

STeVe
Oct 23 '07 #12
On Oct 22, 6:43 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Sunburned Surveyor wrote:
Contents of input text file:
[Name]
Fire Breathing Dragon
[Properties]
Strength
Scariness
Endurance
[Methods]
eatMaiden argMaiden
fightKnight argKnight
Generated Python Class File:
def class FireBreathingDragon:
def getStrength(self):
"""
Docstring goes here.
@return
@rtype
"""
return self.strength
def setStrength(self, argStrength):
"""
Docstring goes here.
@param argStrength
@ptype
"""
return self.strength
def eatMaiden(self, argMaiden):
"""
Docstring goes here.
@param argMaiden
@ptype
"""

This should instead generate::

# Inherit from object. There's no reason to create old-style classes.

We recently had to change an object pipeline from new style classes to
old style. A lot of these objects were being created and the *extra
overhead* of new style classes was killing us. :-)

Michael
http://www.manning.com/foord

Oct 29 '07 #13
Fuzzyman wrote:
On Oct 22, 6:43 pm, Steven Bethard <steven.beth...@gmail.comwrote:
># Inherit from object. There's no reason to create old-style classes.

We recently had to change an object pipeline from new style classes to
old style. A lot of these objects were being created and the *extra
overhead* of new style classes was killing us. :-)
I'm curious. Was it memory or speed overhead that was the problem?

Steve
Oct 29 '07 #14
Fuzzyman a écrit :
On Oct 22, 6:43 pm, Steven Bethard <steven.beth...@gmail.comwrote:
(snip)
># Inherit from object. There's no reason to create old-style classes.


We recently had to change an object pipeline from new style classes to
old style. A lot of these objects were being created and the *extra
overhead* of new style classes was killing us. :-)
Maybe a dumb question, but what about __slots__ here ? (NB : never faced
this kind of problem myself).
Oct 30 '07 #15
Fuzzyman <fu******@gmail.comwrites:
We recently had to change an object pipeline from new style classes
to old style. A lot of these objects were being created and the
*extra overhead* of new style classes was killing us. :-)
Can you please expand on this? What extra overhead of new-style
classes are you referring to?

Memory overhead seems to firmly favor new-style classes, especially
for small object. A trivial small-object allocation test such as

# After running this, use "top" or "ps" to see the ballpark memory
# consumption. Remove "(object)" to measure for old-style class.
python -c 'import time
class A(object): pass
l=[A() for n in xrange(2000000)]
time.sleep(100)'

shows the Python process growing to 78M with a new-style class and to
354M with an old-style class. And that is without even starting to
use actual optimizations, such as using __slots__! Instantiation time
difference is less drastic, but still shows significant improvement
with the use of new-style classes: 0.27 usec for new-style, 0.40 usec
old-style (measured with timeit, subtracted baseline overhead).
Oct 30 '07 #16
On Oct 29, 11:35 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Fuzzyman wrote:
On Oct 22, 6:43 pm, Steven Bethard <steven.beth...@gmail.comwrote:
# Inherit from object. There's no reason to create old-style classes.
We recently had to change an object pipeline from new style classes to
old style. A lot of these objects were being created and the *extra
overhead* of new style classes was killing us. :-)

I'm curious. Was it memory or speed overhead that was the problem?

It was speed overhead - I have to add a disclaimer that this is
IronPython, but my understanding is that the situation is similar with
CPython. Creating new style class instances is slower than for old
style classes.

This was in the execution of spreadsheets, where we had a pipeline of
three objects for each spreadsheet element (not sure if the
implementation is still the same now).

Michael
http://www.manning.com/foord

>
Steve

Oct 30 '07 #17
On Oct 30, 2007 5:52 AM, Fuzzyman <fu******@gmail.comwrote:
On Oct 29, 11:35 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Fuzzyman wrote:
On Oct 22, 6:43 pm, Steven Bethard <steven.beth...@gmail.comwrote:
># Inherit from object. There's no reason to create old-style classes.
We recently had to change an object pipeline from new style classes to
old style. A lot of these objects were being created and the *extra
overhead* of new style classes was killing us. :-)
I'm curious. Was it memory or speed overhead that was the problem?


It was speed overhead - I have to add a disclaimer that this is
IronPython, but my understanding is that the situation is similar with
CPython. Creating new style class instances is slower than for old
style classes.
The obvious timeit test shows new-style classes being created in half
the time of old style ones. I certainly would not generalize to
CPython from IronPythons performance characteristics, especially with
something that's so dependent on both the .NET runtime and on the
details of IronPython integration as object creation.

C:\>python -m timeit -s "class C: pass" "c = C()"
1000000 loops, best of 3: 0.315 usec per loop

C:\>python -m timeit -s "class C(object): pass" "c = C()"
10000000 loops, best of 3: 0.175 usec per loop
Oct 30 '07 #18

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

Similar topics

0
by: Rasmus Fogh | last post by:
Someone raised the question of automatic code generation a few weeks back. And yes, we (CCPN) are using automatic Python code generation in a major way. Basically we are making data models in...
0
by: Rick Hilburger | last post by:
My new non-profit web site is www.getcet.org It's about automatic flow chart generation. I have a program that automatically draws a flow chart next to Python code so that you can see and...
9
by: Maurice LING | last post by:
Hi, Is there any UML tools that is able to take UML and generate Python codes? Cheers Maurice
6
by: Matt | last post by:
I have begun designing and programming in C++ after a several years away from software engineering/programming. I am looking for an "automatic C++ header generator." I have what seems to be...
15
by: Kannan Goundan | last post by:
Maintaining a C++ header file can be painful. I want a way to automatically generate header files from the implementation file. Does anybody know of a program that does this? If not, I'd like...
29
by: Natan | last post by:
When you create and aspx page, this is generated by default: using System; using System.Collections; using System.Collections.Specialized; using System.Configuration; using System.Text; using...
1
by: Lonnie Princehouse | last post by:
I plan on writing some documentation that will consist of blocks of commentary with interspersed snippets of syntax-colored Python code and the occaisional image. Does anyone know of a package...
0
by: JoshforRefugee | last post by:
heard that we can do automatic code generation using macros, but not sure how can I pursue this. Here is my problem. In my env, I have class A,B and C. All of them has constructors, and few...
34
by: =?ISO-8859-1?Q?Marcel_M=FCller?= | last post by:
Hi, is there a way to avoid the automatic copy constructor generation. I do not want the object to be non-copyable. I simply do not want that copying is done by the default copy constructor. But...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
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: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
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)...

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.