Mailing List Archive

Emulating C++ coding style
Hello Everyone!

I usually use C++ ,so I want to make programs like
I do using C++.
I don't figure out how to implement the followings
by Python.
If you know any solutions,Please Help!

1. #define statements
e.g. #define __PYTHON_INCLUDED__
#define PYPROC(ARG) printf("%s",ARG)

2. stream class
e.g. cout << "hello python."<<endl;

3. const variables
e.g. const int NOCHAGE=1;

4. access to class's members using "::"
e.g. some_class::static_value
e.g. some_class::static_func(x)

Thanks for reading.

Thooney Millennier.
Emulating C++ coding style [ In reply to ]
Hi Thooney and all the other Pythonistas out there--

Thooney Millennier wrote:
>
> Hello Everyone!
>
> I usually use C++ ,so I want to make programs like
> I do using C++.
> I don't figure out how to implement the followings
> by Python.
> If you know any solutions,Please Help!
>
> 1. #define statements
> e.g. #define __PYTHON_INCLUDED__
> #define PYPROC(ARG) printf("%s",ARG)
>

__PYTHON_INCLUDED__ = 1

(Although that's probably not what you really mean to do.)

def PYPROC(arg):
print arg

> 2. stream class
> e.g. cout << "hello python."<<endl;
>

print "hello python"

--or--

sys.stdout.write("hello python")


> 3. const variables
> e.g. const int NOCHAGE=1;
>

Can't be done. Any sufficiently determined Pythonista can change
anything she wants to.

But, you can do this to keep your edges inside a specific file--

_NOCHANGE = 1

Any variable beginning with an underscore has module-specific scope.

> 4. access to class's members using "::"
> e.g. some_class::static_value
> e.g. some_class::static_func(x)
>

print some_class.static_value
t = some_class.static_func(x)

See, there's no real concept of a ``static'' member, or of ``private''
members in Python classes. All methods and members of all classes are
public. That's a good thing.

> Thanks for reading.
>
> Thooney Millennier.

You should investigate the tutorial at http://www.python.org

It's really very good, and with your C++ experience you will have no
trouble at all.

<arigato-to-another-newbie>-ly y'rs,
Ivan
----------------------------------------------
Ivan Van Laningham
Callware Technologies, Inc.
ivanlan@callware.com
http://www.pauahtun.org
See also:
http://www.foretec.com/python/workshops/1998-11/proceedings.html
Army Signal Corps: Cu Chi, Class of '70
----------------------------------------------
Emulating C++ coding style [ In reply to ]
Thooney Millennier wrote:
>
> Hello Everyone!
>
> I usually use C++ ,so I want to make programs like
> I do using C++.

Well, first of all, Python is not C++. Some C++ practices don't, and
shouldn't, translate to Python, and vice versa. Python coding style is
different than C++ coding style, just like Java is different yet again,
etc, etc.

> I don't figure out how to implement the followings
> by Python.
> If you know any solutions,Please Help!
>
> 1. #define statements
> e.g. #define __PYTHON_INCLUDED__
Why would you need this? You can use a dictionary and store this kind of
variable in there.

> #define PYPROC(ARG) printf("%s",ARG)

def pyproc(arg):
print "%s" % arg

Python doesn't have a preprocessor.

> 2. stream class
> e.g. cout << "hello python."<<endl;

print "Hello python"

You can override the __str__ method of your own classes determine what
the output for print is for that class.

> 3. const variables
> e.g. const int NOCHAGE=1;

Though trickery is possible, Python does not strictly have any constant
variables. What you can do is use (global) variables with an preceding
underscore. When importing the module these variables are not
accessible. _like_this.

> 4. access to class's members using "::"
> e.g. some_class::static_value
> e.g. some_class::static_func(x)

Python does not support static methods (or 'class methods'). Usually a
module level global function suffices for this purpose.

A static value can be created like this (besides using a global variable
in a module):

class Foo:
self.shared = 1

def __init__(self):
print self.shared


Other people will likely come up or refer to the more complicated ways
to emulate these things in Python, but they're slower and nobody
actually seems to use them in practice.

Python is more dynamic than C++, and that is reflected in the way the
language is used. I hope this helps.

Regards,

Martijn
Emulating C++ coding style [ In reply to ]
On Fri, 23 Apr 1999 06:08:07 +0900, Thooney Millennier wrote:
>Hello Everyone!

Hi!

>I usually use C++ ,so I want to make programs like
>I do using C++.

Bad idea. How many other languages do you know? If you only know C++,
you're now privledged to learn a second language. Part of that is
learning that Good Ideas in one language are Bad Ideas in another.

>I don't figure out how to implement the followings
>by Python.

Okay...

>If you know any solutions,Please Help!

>1. #define statements
> e.g. #define __PYTHON_INCLUDED__

Meaningless in Python. A bad idea in C++, except for #include control
(which isn't needed in Python).

> #define PYPROC(ARG) printf("%s",ARG)

A very bad idea in C++ -- you're supposed to use inline templatized
functions. In Python, just define a function:

def PYPROC(ARG): sys.stdout.write(ARG)

>2. stream class
> e.g. cout << "hello python."<<endl;

VERY bad idea. Bad even in C++.

sys.stdout.write("hello python." + "\n");

>3. const variables
> e.g. const int NOCHAGE=1;

Mediocre idea in C++. Not possible in Python, because in Python variables
aren't supposed to be typed in any way -- instead, they hold things which
are typed.

Why is it only a mediocre idea in C++? Because a constant is part of an
interface, and a free constant is as bad as a free function; it pollutes
the global namespace.

In proper C++, your const will be contained inside a class (probably
static) to keep it out of the global namespace. In proper Python, your
const will also be contained inside a class -- and __setattr__ will be
redefined to disallow changing any values.

class __myConsts:
NOCHAGE = 1
SOMECHAGE = 2

# now make sure nobody can hack my values...
def __setattrs__(self,attrname,value):
raise "can't modify my constants!"

consts = __myConsts()

Now, after you import this module, you can access all your constants
through expressions such as consts.NOCHAGE, but you can't change them.

Well, not quite. It turns out that you CAN change them, but only like
this:

__myConsts.NOCHAGE = 2

...and that only works from within the same file (because names beginning
with underscores are private), so it's probably what you wanted anyhow
(more like Java's 'final' keyword).

>4. access to class's members using "::"
> e.g. some_class::static_value
> e.g. some_class::static_func(x)

In Python, "." works for ALL object access. Pointers, class variables,
and so on don't matter.

To be fair, I think this isn't a bad part of C++; :: notation makes some
things more clear. But Python isn't C++.

>Thanks for reading.

Good luck.

>Thooney Millennier.

--
-William "Billy" Tanksley
"But you shall not escape my iambics."
-- Gaius Valerius Catullus
Emulating C++ coding style [ In reply to ]
Martijn Faassen <faassen@pop.vet.uu.nl> writes:
...
|> 4. access to class's members using "::"
|> e.g. some_class::static_value
|> e.g. some_class::static_func(x)
|
| Python does not support static methods (or 'class methods'). Usually a
| module level global function suffices for this purpose.
|
| A static value can be created like this (besides using a global variable
| in a module):
|
| class Foo:
| self.shared = 1
|
| def __init__(self):
| print self.shared

Just a nit-pick on this particular item - I tried that already, a
couple of days ago, so I know it won't work! You meant to say,

class Foo:
shared = 1

Now a couple of further observations. Per the question, yes, that
variable ("attribute") is accessible in the class scope:

print Foo.shared

As well as in the instance scope, as shown in Martijn's example.
However, it may come as a surprise that if you assign to that attribute
in the instance scope, for example through "self" in a method, what
you get is a new reference bound in the instance scope, and other
instances still see the original class value.

...
def privatize(self):
self.shared = 0

f1 = Foo()
f2 = Foo()
f1.privatize()

print Foo.shared, f1.shared, f2.shared
1 0 1

It's not much like C++ here, but it's uncanny how it reeks of Python!
Namespaces, references!

Donn Cave, University Computing Services, University of Washington
donn@u.washington.edu
Emulating C++ coding style [ In reply to ]
On Fri, 23 Apr 1999 06:08:07 +0900, Thooney Millennier asked about
Python equivalents to C++ code.
>
> >2. stream class
> > e.g. cout << "hello python."<<endl;


On Thu, 22 Apr 1999, William Tanksley replied:

> VERY bad idea. Bad even in C++.
>
> sys.stdout.write("hello python." + "\n");


However, if you *REALLY* want to have that sort of C++ syntax,
you can get it in Python with something like:

endl = '\n'

class OutStream:
def __init__( self, file ):
if hasattr( file, 'write' ):
self.file = file
else:
self.file = open( file, 'w' )
def write( self, what ):
self.file.write( what )
def close( self ):
self.file.close()
def __lshift__(self, what ):
self.write( str(what)+' ')
return self


import sys
out = OutStream( sys.stdout )
out << "Hello" << "World" << endl
out << "The answer is" << 3+4 << endl



---| Steven D. Majewski (804-982-0831) <sdm7g@Virginia.EDU> |---
---| Department of Molecular Physiology and Biological Physics |---
---| University of Virginia Health Sciences Center |---
---| P.O. Box 10011 Charlottesville, VA 22906-0011 |---

Caldera Open Linux: "Powerful and easy to use!" -- Microsoft(*)
(*) <http://www.pathfinder.com/fortune/1999/03/01/mic.html>
Emulating C++ coding style [ In reply to ]
"Steven D. Majewski" wrote:
Steven D. Majewski wrote:

> > > e.g. cout << "hello python."<<endl;

> However, if you *REALLY* want to have that sort of C++ syntax,
> you can get it in Python with something like:

...compare those 15 lines with the zillions of lines
of C++ code!

Michael
--
''''\ Michael Scharf
` c-@@ TakeFive Software
` > http://www.TakeFive.com
\_ V mailto:Michael_Scharf@TakeFive.co.at
Emulating C++ coding style [ In reply to ]
Thooney Millennier <thooney@pk.highway.ne.jp> writes:

> Hello Everyone!
>
> I usually use C++ ,so I want to make programs like
> I do using C++.

Perhaps it would be better to learn how to these things in Python.

> I don't figure out how to implement the followings
> by Python.
> If you know any solutions,Please Help!
>
> 1. #define statements
> e.g. #define __PYTHON_INCLUDED__

This one is not needed in Python. Python's module mechanism, being
considerably less brain-dead than C++'s excuse for a module system,
can actually figure out itself whether a particular module has already
been loaded (gasp!).

> #define PYPROC(ARG) printf("%s",ARG)

Even in C(++), I would solve this like:

int pyproc(const char *arg)
{
return printf("%s", arg);
}

Why bother with the #define ?

> 2. stream class
> e.g. cout << "hello python."<<endl;

Just do:
print "hello python"

If you want a more OO approach, use:
import sys
sys.stdout.write("hello, python" + "\n")

You can replace sys.stdout with any object that bothers to define a write()
method.

> 3. const variables
> e.g. const int NOCHAGE=1;

Sorry, no constants in Python.

> 4. access to class's members using "::"
> e.g. some_class::static_value
> e.g. some_class::static_func(x)

Well, you can do:

class MyClass:
static_value = 1
def static_func(x):
print x

and then:
MyClass.static_value = 2
MyClass.static_func("hello")

However, you get Strange Results(TM) if you access static_value and
static_func() via an instance of MyClass.
So I guess you better ignore this idiom.

There are several other suggestions to simulate a "real" static member
in Python. Read Dejanews for more info. However, the best thing to do
is to just use some other idiom.

For "static methods":
If you really feel they belong to your class, you just create a method
that ignores its "self" parameter. Otherwise, use a global function.

For "static variables":
Make them module-global. Of course, mutations should go via accessor
functions (IMHO), so see "static methods" for more info.

Greetings,

Stephan
Emulating C++ coding style [ In reply to ]
Thooney Millennier wrote:
>
> Hello Everyone!
>
> 2. stream class
> e.g. cout << "hello python."<<endl;

Try StringList.py:

http://starship.skyport.net/~lemburg/StringList.py
or
http://starship.skyport.net/~lemburg/StringList.py.html

>>> import StringList,sys
>>> cout = StringList.StringList()
>>> endl = '\n'
>>> cout << "hello python" << endl
StringList: ['hello python', '\012']
>>> cout.pack() >> sys.stdout
hello python

--
Marc-Andre Lemburg Y2000: 252 days left
---------------------------------------------------------------------
: Python Pages >>> http://starship.skyport.net/~lemburg/ :
---------------------------------------------------------
Emulating C++ coding style [ In reply to ]
> >2. stream class
> > e.g. cout << "hello python."<<endl;
>
> VERY bad idea. Bad even in C++.

Why?
Its one of the 'improvements' over C that allows
overridding of the << operator so that you can
write a class to any stream. Python does similar
with the _str_ mechanism but that doesn't allow
chaining of types together, which I do like in C++

so why is it a bad idea?

Since its off-topic for the group respond by email
if you want...

> In proper C++, your const will be contained inside a class (probably
> static) to keep it out of the global namespace.

Hopefully not. It should be contained within a C++ namespace.

Alan G.

--
=================================================
This post represents the views of the author
and does not necessarily accurately represent
the views of BT.
Emulating C++ coding style [ In reply to ]
William Tanksley <wtanksle@dolphin.openprojects.net> wrote:
> On Fri, 23 Apr 1999 06:08:07 +0900, Thooney Millennier wrote:
> >2. stream class
> > e.g. cout << "hello python."<<endl;
>
> VERY bad idea. Bad even in C++.

Out of curiosity, why is this a "VERY bad idea"? Personally, I really like
the ideas behind the streams interface in C++ (though the implementations
are usually somewhat lacking) and use Python file objects in the same
manner. Am I doing something wrong?

For that matter, I don't see how C++ streams are really any different than
Python's file objects. To summarise:

In C++: Base interface definition in {i,o}stream and streambuf.
In Python: Base interface definition in file objects.

In C++: New streams are defined by inheriting from {i,o}stream and
streambuf, and by providing an implementation for the relevant
methods.
In Python: New streams are defined by providing methods with the same
name and arguments as those for files.

In C++: User-defined classes are streamed in/out by providing:
ostream& operator << (ostream&, UserClass const&)
istream& operator >> (istream&, UserClass&)
methods/functions (or by using a persistence library).
In Python: Classes are streamed in/out by providing a __str__() method
or by using one of the (nicely built-in :-) persistence
modules.

The biggest difference that I can see is that C++ methods are static (i.e.,
checked and linked at compile time) vs. dynamic in Python (which is how you
get away without inheriting from a file base class). But this isn't
specific to streams.
Emulating C++ coding style [ In reply to ]
On Fri, 23 Apr 1999 13:28:12 +0100, Alan Gauld wrote:
>> >2. stream class
>> > e.g. cout << "hello python."<<endl;

>> VERY bad idea. Bad even in C++.

>Why?

Very good question. Okay, so I like hyperbole. Thanks for calling me on
it ;-). You're right.

>Its one of the 'improvements' over C that allows
>overridding of the << operator so that you can
>write a class to any stream. Python does similar
>with the _str_ mechanism but that doesn't allow
>chaining of types together, which I do like in C++

>so why is it a bad idea?

The reason I don't like it -- or why I didn't when I posted -- is that
it's a yukky overloading. It makes a symbol mean something _entirely_
different from its usual meaning.

The reason I'm eating my words is that although it may be bad to _design_
an operator function which behaves so badly, it's not always bad to use an
already (badly) designed operator, so long as it's unambiguous. And
whatever I might say about C++'s << operator, it's not ambiguous in
practice.

In other words, the designer(s) of C++ may have given the C++ world a bad
example with the << op, but they sure did a good job choosing which
operator to implement.

>Since its off-topic for the group respond by email
>if you want...

Someone else asked, so I figger it's okay.

Plus, since Python 2.0 is in its early requirements-gathering phase, maybe
it wouldn't hurt to think about issues like this.

>> In proper C++, your const will be contained inside a class (probably
>> static) to keep it out of the global namespace.

>Hopefully not. It should be contained within a C++ namespace.

Okay, I'll bite. Why "hopefully not" a class? I know namespaces are new
and cool, but classes seem to have done the job very well in the past.
Have they been secretly causing bloat in our code all along ;-)?

>Alan G.

--
-William "Billy" Tanksley
"But you shall not escape my iambics."
-- Gaius Valerius Catullus
Emulating C++ coding style [ In reply to ]
Donn Cave wrote:
>
> Martijn Faassen <faassen@pop.vet.uu.nl> writes:
> | A static value can be created like this (besides using a global variable
> | in a module):
> |
> | class Foo:
> | self.shared = 1
> |
> | def __init__(self):
> | print self.shared
>
> Just a nit-pick on this particular item - I tried that already, a
> couple of days ago, so I know it won't work! You meant to say,
>
> class Foo:
> shared = 1

Whoops, yes, that makes sense. :) Sorry.

> Now a couple of further observations. Per the question, yes, that
> variable ("attribute") is accessible in the class scope:
>
> print Foo.shared
>
> As well as in the instance scope, as shown in Martijn's example.

[snip surprise]
> It's not much like C++ here, but it's uncanny how it reeks of Python!
> Namespaces, references!

Indeed. Not having used that class attribute trick often myself, I
wasn't aware of this surprising behavior. I suppose in order to get the
C++ behavior it's best to use a module global variable.

Regards,

Martijn
Emulating C++ coding style [ In reply to ]
Martijn Faassen <faassen@pop.vet.uu.nl> writes:
| Donn Cave wrote:
...
|> It's not much like C++ here, but it's uncanny how it reeks of Python!
|> Namespaces, references!
|
| Indeed. Not having used that class attribute trick often myself, I
| wasn't aware of this surprising behavior. I suppose in order to get the
| C++ behavior it's best to use a module global variable.

Not at all, either way is fine - the class scope is just as good a place
as the module scope, for me it's the perfect place for things that are
specific to the class.

It's the usage that you have to watch out for, and while there are some
perils for the unwary, in the long run it's also an opportunity to gain
a deeper understanding of how simple Python is. Same for module attributes -
common problem, someone imports a module attribute like

from foo import shared
shared = 5

and then wonders, how come no change to the attribute as seen from other
modules. The right way to set to a module attribute - if you must do this
at all - is

foo.shared = 5

and just the same for a class attribute (of class Foo):

from foo import Foo
Foo.shared = 5

In general, you have the problem only when your usage doesn't reflect the
design. If it's really a class attribute, but you set it in the instance
scope, if it's really an external module attribute but you bind it into
the present module's scope during import. Python bites if you trick it.

Donn Cave, University Computing Services, University of Washington
donn@u.washington.edu
Emulating C++ coding style [ In reply to ]
William Tanksley wrote:
>
> On Fri, 23 Apr 1999 13:28:12 +0100, Alan Gauld wrote:

<<snip>>

>
> >> In proper C++, your const will be contained inside a class (probably
> >> static) to keep it out of the global namespace.
>
> >Hopefully not. It should be contained within a C++ namespace.
>
> Okay, I'll bite. Why "hopefully not" a class? I know namespaces are new
> and cool, but classes seem to have done the job very well in the past.
> Have they been secretly causing bloat in our code all along ;-)?

Classes are semantically "heavier" than namespaces: by design, they exist to
classify objects. Classes which exist only to scope other names (typedefs,
constants, free functions), while a decent workaround before the ANSI standard,
are now less attractive (they can't be reopened, for one thing).

--
=========================================================
Tres Seaver tseaver@palladion.com 713-523-6582
Palladion Software http://www.palladion.com
Emulating C++ coding style [ In reply to ]
On Wed, 28 Apr 1999 23:21:41 -0500, Tres Seaver wrote:
>William Tanksley wrote:

>> On Fri, 23 Apr 1999 13:28:12 +0100, Alan Gauld wrote:

>> >> In proper C++, your const will be contained inside a class (probably
>> >> static) to keep it out of the global namespace.

>> >Hopefully not. It should be contained within a C++ namespace.

>> Okay, I'll bite. Why "hopefully not" a class? I know namespaces are new
>> and cool, but classes seem to have done the job very well in the past.
>> Have they been secretly causing bloat in our code all along ;-)?

>Classes are semantically "heavier" than namespaces: by design, they exist to
>classify objects. Classes which exist only to scope other names (typedefs,
>constants, free functions), while a decent workaround before the ANSI standard,
>are now less attractive (they can't be reopened, for one thing).

Now that makes a lot of sense.

However, investigating my code for compliance with this statement, I find
that every time I've declared consts or enums it's always been part of a
class's state. So I can't just move it out into a namespace without
having it look odd.

In the future, though, my design will include the use of namespaces for
inherited state enumerations (i.e. ones which descendant classes may be
expected to use).

What does THIS, you ask, have to do with Python? Well, it serves to
reiterate my point: don't break a cool feature by not planning it out
completely. C++ broke a LOT of things that way.

Speaking of which, I'm kind of wondering how to take the address of a
function in C++ in the presence of overloading. In C it was trivial, but
in C++ you can't distinguish between different functions based only on
names. Odd... I can't find anything which mentions how to do that.

>Tres Seaver tseaver@palladion.com 713-523-6582

--
-William "Billy" Tanksley
"But you shall not escape my iambics."
-- Gaius Valerius Catullus