How do these Java concepts translate to Python?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ray

    #1

    How do these Java concepts translate to Python?

    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

    #2
    Re: How do these Java concepts translate to Python?


    Ray wrote:
    [color=blue]
    > 1. Where are the access specifiers? (public, protected, private)[/color]

    AFAIK, there is not such a thing in Python.

    ---Fausto


    Comment

    • Devan L

      #3
      Re: How do these Java concepts translate to Python?


      Fausto Arinos Barbuto wrote:[color=blue]
      > Ray wrote:
      >[color=green]
      > > 1. Where are the access specifiers? (public, protected, private)[/color]
      >
      > AFAIK, there is not such a thing in Python.
      >
      > ---Fausto[/color]

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

      Comment

      • Ray

        #4
        Re: How do these Java concepts translate to Python?

        Fausto Arinos Barbuto wrote:[color=blue]
        > Ray wrote:
        >[color=green]
        > > 1. Where are the access specifiers? (public, protected, private)[/color]
        >
        > AFAIK, there is not such a thing in Python.[/color]

        So everything is public? I know that you can prefix a member with
        underscores to make something private, but how about protected, for
        example?
        [color=blue]
        >
        > ---Fausto[/color]

        Comment

        • Ray

          #5
          Re: How do these Java concepts translate to Python?

          Devan L wrote:[color=blue]
          > Fausto Arinos Barbuto wrote:[color=green]
          > > Ray wrote:
          > >[color=darkred]
          > > > 1. Where are the access specifiers? (public, protected, private)[/color]
          > >
          > > AFAIK, there is not such a thing in Python.
          > >
          > > ---Fausto[/color]
          >
          > Well, technically you can use _attribute to mangle it, but technically
          > speaking, there are no public, protected, or private things.[/color]

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

          Thanks
          Ray

          Comment

          • Steven Bethard

            #6
            Re: How do these Java concepts translate to Python?

            Ray wrote:[color=blue]
            > 1. Where are the access specifiers? (public, protected, private)[/color]

            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.
            [color=blue]
            > 2. How does Python know whether a class is new style or old style?
            > E.g.:
            >
            > class A:
            > pass[/color]

            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.
            [color=blue]
            > 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?[/color]

            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 "<interacti ve 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

            Comment

            • Jeff Schwab

              #7
              Re: How do these Java concepts translate to Python?

              Ray wrote:[color=blue]
              > Devan L wrote:
              >[color=green]
              >>Fausto Arinos Barbuto wrote:
              >>[color=darkred]
              >>>Ray wrote:
              >>>
              >>>
              >>>>1. Where are the access specifiers? (public, protected, private)
              >>>
              >>> AFAIK, there is not such a thing in Python.
              >>>
              >>>---Fausto[/color]
              >>
              >>Well, technically you can use _attribute to mangle it, but technically
              >>speaking, there are no public, protected, or private things.[/color]
              >
              >
              > OK, thanks. How about static members and instance members? Seems that
              > in Python everything is class-wide?[/color]

              You can define instance data in the __init__ method.

              def __init__(self):
              self.instance_m ember = 0;

              Comment

              • Paul McGuire

                #8
                Re: How do these Java concepts translate to Python?

                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(o bject):
                """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,i nitArgs=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(initWithThisV alue)
                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.instanceVa r = initArgs
                else:
                self.instanceVa r = 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(st aticMethod)
                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.instanceMe thod(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.__hiddenMe thod(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.__hiddenMetho d(5,6,7) # Not allowed!

                Comment

                • Ben Finney

                  #9
                  Re: How do these Java concepts translate to Python?

                  Ray <ray_usenet@yah oo.com> wrote:[color=blue]
                  > 1. Where are the access specifiers? (public, protected, private)[/color]

                  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.
                  [color=blue]
                  > 2. How does Python know whether a class is new style or old style?
                  > E.g.:
                  >
                  > class A:
                  > pass[/color]

                  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
                  [color=blue]
                  > 3. In Java we have static (class) method and instance members. But
                  > this difference seems to blur in Python.[/color]

                  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.i d.au/>

                  Comment

                  • Paul McGuire

                    #10
                    Re: How do these Java concepts translate to Python?

                    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

                    Comment

                    • Ray

                      #11
                      Re: How do these Java concepts translate to Python?

                      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>

                      Comment

                      • bruno modulix

                        #12
                        Re: How do these Java concepts translate to Python?

                        Ray wrote:[color=blue]
                        > 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)[/color]

                        object.name => public
                        object._name => protected
                        object.__name => private
                        [color=blue]
                        > 2. How does Python know whether a class is new style or old style?
                        > E.g.:
                        >
                        > class A:
                        > pass[/color]

                        This is an old-style class.
                        [color=blue]
                        > 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?[/color]

                        class B(object): # or any subclass of object
                        pass
                        [color=blue]
                        > 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?[/color]

                        Depends if you bind it to the class or to the instance !-)
                        [color=blue]
                        > It seems that everything
                        > is static (in the Java sense) in Python. Am I correct?[/color]

                        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)
                        [color=blue]
                        > Thanks in advance,[/color]

                        HTH



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

                        Comment

                        • bruno modulix

                          #13
                          Re: How do these Java concepts translate to Python?

                          Devan L wrote:[color=blue]
                          > Fausto Arinos Barbuto wrote:
                          >[color=green]
                          >>Ray wrote:
                          >>
                          >>[color=darkred]
                          >>>1. Where are the access specifiers? (public, protected, private)[/color]
                          >>
                          >> AFAIK, there is not such a thing in Python.
                          >>
                          >>---Fausto[/color]
                          >
                          >
                          > Well, technically you can use _attribute to mangle it,[/color]

                          __attribute would work better !-)
                          [color=blue]
                          > but technically
                          > speaking, there are no public, protected, or private things.[/color]

                          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
                          python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                          p in 'onurb@xiludom. gro'.split('@')])"

                          Comment

                          • bruno modulix

                            #14
                            Re: How do these Java concepts translate to Python?

                            Ray wrote:[color=blue]
                            > Fausto Arinos Barbuto wrote:
                            >[color=green]
                            >>Ray wrote:
                            >>
                            >>[color=darkred]
                            >>>1. Where are the access specifiers? (public, protected, private)[/color]
                            >>
                            >> AFAIK, there is not such a thing in Python.[/color]
                            >
                            >
                            > So everything is public? I know that you can prefix a member with
                            > underscores to make something private,[/color]

                            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
                            [color=blue]
                            > but how about protected, for
                            > example?[/color]

                            object._protect ed_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 ?-)


                            --
                            bruno desthuilliers
                            python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                            p in 'onurb@xiludom. gro'.split('@')])"

                            Comment

                            • Roy Smith

                              #15
                              Re: How do these Java concepts translate to Python?

                              "Ray" <ray_usenet@yah oo.com> wrote:[color=blue]
                              > 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)[/color]

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

                              Slightly longer answer; if you name an attribute with two leading
                              underscores (i.e. "__myPrivateDat a"), 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.

                              Comment

                              Working...