Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do these Java concepts translate to Python?

4 views
Skip to first unread message

Ray

unread,
Aug 11, 2005, 11:00:46 PM8/11/05
to
Hello,

I've been learning Python in my sparetime. I'm a Java/C++ programmer by
trade. So I've been reading about Python OO, and I have a few questions
that I haven't found the answers for :)

1. Where are the access specifiers? (public, protected, private)
2. How does Python know whether a class is new style or old style?
E.g.:

class A:
pass

How does it know whether the class is new style or old style? Or this
decision only happens when I've added something that belongs to new
style? How do I tell Python which one I want to use?

3. In Java we have static (class) method and instance members. But this
difference seems to blur in Python. I mean, when you bind a member
variable in Python, is it static, or instance? It seems that everything
is static (in the Java sense) in Python. Am I correct?

Thanks in advance,
Ray

Fausto Arinos Barbuto

unread,
Aug 11, 2005, 11:27:44 PM8/11/05
to

Ray wrote:

> 1. Where are the access specifiers? (public, protected, private)

AFAIK, there is not such a thing in Python.

---Fausto


Devan L

unread,
Aug 11, 2005, 11:30:14 PM8/11/05
to

Well, technically you can use _attribute to mangle it, but technically
speaking, there are no public, protected, or private things.

Ray

unread,
Aug 11, 2005, 11:31:27 PM8/11/05
to

So everything is public? I know that you can prefix a member with
underscores to make something private, but how about protected, for
example?

>
> ---Fausto

Ray

unread,
Aug 11, 2005, 11:39:05 PM8/11/05
to

OK, thanks. How about static members and instance members? Seems that
in Python everything is class-wide?

Thanks
Ray

Steven Bethard

unread,
Aug 12, 2005, 12:36:07 AM8/12/05
to
Ray wrote:
> 1. Where are the access specifiers? (public, protected, private)

There's no enforceable way of doing these. The convention is that names
that begin with a single underscore are private to the
class/module/function/etc. Hence why sys._getframe() is considered a
hack -- it's not officially part of the sys module.

> 2. How does Python know whether a class is new style or old style?
> E.g.:
>
> class A:
> pass

That's an old-style class. All new-style classes inherit from object
(or another new-style class). So write it like:

class A(object):
pass

If you're just learning Python now, there's really no reason to use
old-style classes. They're only there for backwards compatibility.

> 3. In Java we have static (class) method and instance members. But this
> difference seems to blur in Python. I mean, when you bind a member
> variable in Python, is it static, or instance? It seems that everything
> is static (in the Java sense) in Python. Am I correct?

No, there's a difference, but things can get a little tricky. We'll
start with the easy one:

py> class A(object):
... x = 0 # "static", class-level
... def __init__(self):
... self.y = 1 # "non-static", instance-level
...

The difference between a "static", class-level attribute and a
"non-static", instance-level attribute is whether it's set on the class
object (e.g. in the class definition), or on the instance object (e.g.
by writing self.XXX = YYY). Playing with this a bit:

py> a = A()
py> A.x # read the class-level "x"
0
py> a.x # read the *class*-level "x" (but search through the instance)
0
py> A.y # try to read a class-level "y"
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: type object 'A' has no attribute 'y'
py> a.y # read the instance-level "y"
1

Note that you can read "static" attributes from both the class and the
instance, and you can only read "non-static" attributes from the
instance, just like Java (IIRC).

Where you're likely to get confused is that instance level attributes
can shadow the class level attributes. That is, if you set an instance
attribute with the same name as a class attribute, you can't find the
class attribute through that instance anymore:

py> a.x = 2 # set the *instance*-level "x"
py> A.x # read the *unchanged* class-level "x"
0
py> a.x # read the *changed* instance-level "x"
2

HTH,

STeVe

Jeff Schwab

unread,
Aug 12, 2005, 12:39:04 AM8/12/05
to

You can define instance data in the __init__ method.

def __init__(self):
self.instance_member = 0;

Paul McGuire

unread,
Aug 12, 2005, 12:55:06 AM8/12/05
to
Please look through this example code, and the comments. If I've
misspoken, please anyone correct my errors.

-- Paul


class OldStyleClass:
"""A definition of an old style class."""
pass

class NewStyleClass(object):
"""Note that NewStyleClass explicitly inherits from object. This
is what makes it new-style."""
pass

class B(object):
pass

class C(object):
pass

class A(B,C):
"""Class A inherits from classes B and C. Since they are new-style,
A is new-style, too."""

# this is a class variable of A.
classVar = 0

def __init__(self,initArgs=None):
"""This string documents this routine, which is the initializer

for new instances. __init__ is not typically explicitly
called (except from subclasses), but is automatically called

when creating new instances of class A, as in:
aObj = A(initWithThisValue)
Since initArgs is declared with a default value, it is also
possible to create an object as:
aObj = A()
and __init__ will be invoked with None as the value of
initArgs.
"""
if initArgs is not None:
self.instanceVar = initArgs
else:
self.instanceVar = 0

@staticmethod
def staticMethod(a,b,c):
"""This is a class-level method. Presumably it has something
to do with this class, perhaps as a factory or other
utility method.

This method is invoked as:
A.staticMethod(100, ['A','B'], 3.14159)

What makes this a static method is the @staticmethod
decorator that precedes the class definition.
(Pre-2.4 code would use the form:
staticMethod = staticmethod(staticMethod)
in place of the @staticmethod decorator.)
"""
pass

@classmethod
def classMethod(cls,d,e,f):
"""This is also a class-level method, but is distinct in that
the class is implicitly passed as the first argument,
although the caller does not pass the class in.

This method looks similar to the static method invocation:
A.classMethod(5,'XYZZY',[])

But in this case, the variable cls takes the value of the
class used to invoke the method, either A or some subclass
of A.
"""
print cls,type(cls)

def instanceMethod(self,g,h,i):
"""By default, this method is assumed to be an instance
method. The first argument in the list is the object's
own reference variable - by convention this is near-
universally named 'self', although some prefer the
variable name '_'. Any variable will do really, such
as 'me', 'this', 'I', etc., but it is the first variable
in the list.

The caller does not explicitly pass this object reference
variable in the calling arg list. Invoking instanceMethod
looks like:
aVar = A()
aVar.instanceMethod(1,2,3)
"""
pass

def __hiddenMethod(self,x,y,z):
"""By the magic of the leading '__' on this method name,
this method is not externally visible. It *can* be
called from derived classes, though, so it can be thought
of as roughly analogous to being a 'protected' method
in C++ or Java (although as I recall, 'protected' in
Java isn't really all that protected).

Leading '__' can also be used to hide instance and class
vars, too.
"""
pass

# Here is how you define a class-level variable of A that is of type A.
# You could use these to predefine special A variables, as in
# simulating an enum, or in creating some common values of a given
# class, such as Color.RED, Color.GREEN, etc.
A.specialA = A("special")
A.unusualA = A("unusual")

class G(A):
"""A subclass of A, used to demonstrate calling a classmethod,
and a hidden method."""
pass

def tryHidden(self):
# call a method defined in the superclass
self.__hiddenMethod(4,5,6)

# Invoke some class-methods. The first call will pass the class A
# as the first arg, the second will pass the class G as the first arg.
A.classMethod(1,2,3)
G.classMethod(4,5,6)

g = G()
g.tryHidden() # Allowed
g.__hiddenMethod(5,6,7) # Not allowed!

Ben Finney

unread,
Aug 12, 2005, 1:23:07 AM8/12/05
to
Ray <ray_u...@yahoo.com> wrote:
> 1. Where are the access specifiers? (public, protected, private)

No such thing (or, if you like, everything is "private" by default).

By convention, "please don't access this name externally" is indicated
by using the name '_foo' instead of 'foo'; similar to a "protected".
Nothing in the language enforces this.

Recently, the language came to partially support '__foo' (i.e. a name
beginning with two underscores) as a pseudo-"private". It's just a
namespace munging though; sufficiently determined users can get at it
without much effort.

The attitude engendering this simplicity is "we're all consenting
adults here". If you have users of your modules and classes who won't
respect access restriction *conventions*, they're bad programmers
anyway, so there's not much the language can do to stop that.

> 2. How does Python know whether a class is new style or old style?
> E.g.:
>
> class A:
> pass

New-style classes are descended from class 'object'. Old-style classes
aren't.

Thus, your example above is an old-style class, as are any classes
that inherit only from that class.

To create a new-style class with no particular base functionality,
inherit from 'object' directly:

class A(object):
pass

> 3. In Java we have static (class) method and instance members. But
> this difference seems to blur in Python.

Class attributes and instance attributes are distinguished by the fact
that instance attributes are created when the instance is created
(typically, assigned within the __init__() method):

class A(object):
foo = 'Fudge'
def __init__(self, bar):
self.bar = bar

wibble = A('Wibble')
print wibble.foo, wibble.bar # Fudge Wibble
bobble = A('Bobble')
print bobble.foo, bobble.bar # Fudge Bobble

Instances of the 'A' class all share a 'foo' attribute, and each
instance has its own 'bar' attribute created separately (in the
__init__() method).

--
\ "Unix is an operating system, OS/2 is half an operating system, |
`\ Windows is a shell, and DOS is a boot partition virus." -- |
_o__) Peter H. Coffin |
Ben Finney <http://www.benfinney.id.au/>

Paul McGuire

unread,
Aug 12, 2005, 1:38:10 AM8/12/05
to
Instance variables are typically defined in __init__(), but they can be
added to an object anywhere. The only exception is when defining the
magic __slots__ class variable to pre-define what the allowed instance
variables can be.

class A:
pass

a = A()
a.instVar1 = "hoo-ah"
a.instVar2 = "another"

Try that in C++ or Java!

-- Paul

Ray

unread,
Aug 12, 2005, 1:53:33 AM8/12/05
to
Thanks guys! Your explanations have cleared up things significantly.

My transition from C++ to Java to C# was quite painless because they
were so similar, but Python is particularly challenging because the
concepts are quite different. (I always have this paranoid feeling: "Am
I using Python to write Java, or using Python to write Python?")

Regards,
Ray


Ray wrote:
<snipped>

bruno modulix

unread,
Aug 12, 2005, 4:51:37 AM8/12/05
to
Ray wrote:
> Hello,
>
> I've been learning Python in my sparetime. I'm a Java/C++ programmer by
> trade. So I've been reading about Python OO, and I have a few questions
> that I haven't found the answers for :)
>
> 1. Where are the access specifiers? (public, protected, private)

object.name => public
object._name => protected
object.__name => private

> 2. How does Python know whether a class is new style or old style?
> E.g.:
>
> class A:
> pass

This is an old-style class.

> How does it know whether the class is new style or old style? Or this
> decision only happens when I've added something that belongs to new
> style? How do I tell Python which one I want to use?

class B(object): # or any subclass of object
pass

> 3. In Java we have static (class) method and instance members. But this
> difference seems to blur in Python. I mean, when you bind a member
> variable in Python, is it static, or instance?

Depends if you bind it to the class or to the instance !-)

> It seems that everything
> is static (in the Java sense) in Python. Am I correct?

No.

class Foo(object):
bar = 42 # this is a class variable

# __init__ is the equivalent of Java constructors
def __init__(self, baaz):
self.baaz = baaz # this is an instance variable

# this is a class method
# (the first argument is the class object, not the instance)
@classmethod
def bak(cls, frooz):
cls.bar = min(cls.bar, frooz) + 1138

# default is instance method
def zoor(self):
print "%s %d" % (self.baaz, Foo.bar)

> Thanks in advance,

HTH

--
bruno desthuilliers
ruby -e "print 'on...@xiludom.gro'.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"

bruno modulix

unread,
Aug 12, 2005, 4:55:40 AM8/12/05
to
Devan L wrote:
> Fausto Arinos Barbuto wrote:
>
>>Ray wrote:
>>
>>
>>>1. Where are the access specifiers? (public, protected, private)
>>
>> AFAIK, there is not such a thing in Python.
>>
>>---Fausto
>
>
> Well, technically you can use _attribute to mangle it,

__attribute would work better !-)

> but technically
> speaking, there are no public, protected, or private things.

Yes there are:
object.name is public
object._name is protected
object.__name is private

You don't need the language to enforce this, it's just a matter of
conventions.


--
bruno desthuilliers

bruno modulix

unread,
Aug 12, 2005, 5:09:40 AM8/12/05
to
Ray wrote:
> Fausto Arinos Barbuto wrote:
>
>>Ray wrote:
>>
>>
>>>1. Where are the access specifiers? (public, protected, private)
>>
>> AFAIK, there is not such a thing in Python.
>
>
> So everything is public? I know that you can prefix a member with
> underscores to make something private,

The "2 leadings underscore name mangling" scheme is intented to protect
"sensible" attributes from being accidentally overriden by derived
classes, not to prevent access to the attribute.

class Foo(object):
def __init__(self):
self.__baaz = 42

f = Foo()
print f._Foo__baaz

> but how about protected, for
> example?

object._protected_attribute is enough to tell anyone not to mess with
this attribute. Believe it or else, but this happens to work perfectly.

And BTW, don't bother making all your attributes "protected" or
"private" then writing getters and setters, Python has a good support
for computed attributes, so you can change the implementation without
problem (which is the original reason for not-public attributes):

# first version:
class Foo(object):
def __init__(self):
self.baaz = 42 # public attribute

# later we discover that we want Foo.baaz to be computed:
class Foo(object):
def __init__(self):
self.baaz = 42

def _set_baaz(self, value):
if value < 21 or value > 84:
raise ValueError, "baaz value must be in range 21..84"
self._baaz = value

def _get_baaz(self):
return self._baaz * 2

baaz = property(fget=_get_baaz, fset=_set_baaz)

Easy as pie, uh ?-)

Roy Smith

unread,
Aug 12, 2005, 8:32:09 AM8/12/05
to
"Ray" <ray_u...@yahoo.com> wrote:
> I've been learning Python in my sparetime. I'm a Java/C++ programmer by
> trade. So I've been reading about Python OO, and I have a few questions
> that I haven't found the answers for :)
>
> 1. Where are the access specifiers? (public, protected, private)

Quick answer; there are none, all attributes are public.

Slightly longer answer; if you name an attribute with two leading
underscores (i.e. "__myPrivateData"), there is some name mangling that goes
on which effectively makes the attribute private. There are ways around
it, but you have to know what you're doing and deliberately be trying to
spoof the system (but, then again, exactly the same can be said for C++'s
private data).

Soapbox answer; private data is, in some ways, a useful tool, but it is not
part and parcel of object oriented programming. I've had people (mostly
C++/Java weenies) that Python is not an OOPL because it does not enforce
data hiding. "Feh", I say to them.

Ray

unread,
Aug 12, 2005, 10:09:13 AM8/12/05
to

bruno modulix wrote:
<snipped>


> And BTW, don't bother making all your attributes "protected" or
> "private" then writing getters and setters, Python has a good support
> for computed attributes, so you can change the implementation without
> problem (which is the original reason for not-public attributes):

Thanks Bruno! This is good stuff. This is exactly what I want to avoid:
writing Java in Python.

Cheers,
Ray

Ray

unread,
Aug 12, 2005, 10:41:51 AM8/12/05
to
Roy Smith wrote:
> Quick answer; there are none, all attributes are public.
>
> Slightly longer answer; if you name an attribute with two leading
> underscores (i.e. "__myPrivateData"), there is some name mangling that goes
> on which effectively makes the attribute private. There are ways around
> it, but you have to know what you're doing and deliberately be trying to
> spoof the system (but, then again, exactly the same can be said for C++'s
> private data).

Well yeah... if you really want it, in Java you can do that too via
reflection. Just that I'm not used to it yet so I feel a bit jittery
with so much power on my hands!

> Soapbox answer; private data is, in some ways, a useful tool, but it is not
> part and parcel of object oriented programming. I've had people (mostly
> C++/Java weenies) that Python is not an OOPL because it does not enforce
> data hiding. "Feh", I say to them.

Feh... those weenies don't know what they're talkin about.

Aahz

unread,
Aug 12, 2005, 11:42:02 AM8/12/05
to
In article <ddhbnr$lui$1...@rose.polar.local>,

Ben Finney <bignose+h...@benfinney.id.au> wrote:
>
>Recently, the language came to partially support '__foo' (i.e. a name
>beginning with two underscores) as a pseudo-"private". It's just a
>namespace munging though; sufficiently determined users can get at it
>without much effort.

Recently?
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

The way to build large Python applications is to componentize and
loosely-couple the hell out of everything.

bruno modulix

unread,
Aug 12, 2005, 12:20:17 PM8/12/05
to
Ray wrote:
> Roy Smith wrote:
>
>>Quick answer; there are none, all attributes are public.
>>
(snip)

>
> Well yeah... if you really want it, in Java you can do that too via
> reflection. Just that I'm not used to it yet so I feel a bit jittery
> with so much power on my hands!

Then wait until you discover what one can do with __magic_methods__,
functions-as-objects, closures, callable objects, descriptors
(properties on steroids), decorators, generators, and metaclasses...
*Then* you'll know what power means !-)

And more is to come...

Ray

unread,
Aug 12, 2005, 12:41:18 PM8/12/05
to
bruno modulix wrote:
> Then wait until you discover what one can do with __magic_methods__,
> functions-as-objects, closures, callable objects, descriptors
> (properties on steroids), decorators, generators, and metaclasses...
> *Then* you'll know what power means !-)
>
> And more is to come...

... I've got a feeling that this Pythonic journey will expand my brain
so much ;)

Steven Bethard

unread,
Aug 12, 2005, 1:19:39 PM8/12/05
to
bruno modulix wrote:
>>but technically
>>speaking, there are no public, protected, or private things.
>
> Yes there are:
> object.name is public
> object._name is protected
> object.__name is private

The double-underscore name-mangling is almost never worth it. It's
supposed to stop name collisions, but, while it does in some cases, it
doesn't in all cases, so you shouldn't rely on this. For example:

---------- mod1.py ----------
class C(object):
__x = 'mod1.C'
@classmethod
def getx(cls):
return cls.__x
-----------------------------

---------- mod2.py ----------
import mod1
class C(mod1.C):
__x = 'mod2.C'
-----------------------------

py> import mod1, mod2
py> mod1.C.getx()
'mod1.C'
py> mod2.C.getx()
'mod2.C'

If double-underscore name-mangling worked like private variables,
setting C.__x in mod2.C should not affect the value of C.__x in mod1.C.

STeVe

gene tani

unread,
Aug 12, 2005, 4:50:00 PM8/12/05
to

Ray

unread,
Aug 12, 2005, 9:58:08 PM8/12/05
to

Thanks gene, these are exactly the stuff I wanna know more about.

Ray

0 new messages