namespace question

Discussion in 'Python' started by xixiliguo, Feb 24, 2012.

  1. xixiliguo

    xixiliguo Guest

    c = [1, 2, 3, 4, 5]
    class TEST():
    c = [5, 2, 3, 4, 5]
    def add( self ):
    c[0] = 15

    a = TEST()


    a.add()

    print( c, a.c, TEST.c )

    result :
    [15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]


    why a.add() do not update c in Class TEST? but update c in main file
     
    xixiliguo, Feb 24, 2012
    #1
    1. Advertising

  2. xixiliguo

    Chris Rebert Guest

    On Thu, Feb 23, 2012 at 9:55 PM, xixiliguo <> wrote:
    > c = [1, 2, 3, 4, 5]
    > class TEST():
    >    c = [5, 2, 3, 4, 5]


    That line creates a class (i.e. "static") variable, which is unlikely
    to be what you want. Instance variables are normally created in the
    body of an __init__() method.

    >    def add( self ):
    >        c[0] = 15
    >
    > a = TEST()
    >
    >
    > a.add()
    >
    > print( c, a.c, TEST.c )
    >
    > result :
    > [15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]
    >
    >
    > why a.add() do not update c in Class TEST? but update c in main file


    Python is not Java (or similar). To refer to instance variables, you
    must explicitly use `self`; i.e. use "self.c[0] = 15" in add().

    I would recommend reviewing the relevant section of the Python tutorial:
    http://docs.python.org/tutorial/classes.html

    Cheers,
    Chris
     
    Chris Rebert, Feb 24, 2012
    #2
    1. Advertising

  3. xixiliguo wrote:
    > c = [1, 2, 3, 4, 5]
    > class TEST():
    > c = [5, 2, 3, 4, 5]
    > def add( self ):
    > c[0] = 15
    >
    > a = TEST()
    >
    >
    > a.add()
    >
    > print( c, a.c, TEST.c )
    >
    > result :
    > [15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]
    >
    >
    > why a.add() do not update c in Class TEST? but update c in main file
    >


    Attributes can only accessed by explictly naming the owner, unlike some
    other languages which infer 'this/self'.
    When an attribute is not found in the owner, python may look into the
    "outer" namespace. Read the python documentation for an accurate
    description.


    Here is an illustration (python 2.5):

    c='global'

    class TEST():
    c = 'class'
    d = 'classonly'
    def __init__(self):
    self.c='instance'
    def test(self):
    print c
    print TEST.c
    print self.c
    print self.d # this is valid, if d is not found in the instance,
    python will look into the class

    t = TEST()

    t.test()

    global
    class
    instance
    classonly


    Note that objects in python are properly named namespaces. locals and
    globals are not, so be careful while naming those (in few words: don't
    use globals)

    c = 'global'

    def foo():
    c = 'local'
    print c # same name for 2 different objects

    def bar():
    print c
    global c # the global statement is quite strange, it applies to the
    whole block, even previous statements, ppl usually put it at the
    begining of the block though

    foo()
    bar()

    'local'
    'global'

    Cheers,

    JM
     
    Jean-Michel Pichavant, Feb 24, 2012
    #3
  4. xixiliguo

    David Guest

    Your code updated to show the difference between a variable, a class
    variable, and an instance variable.
    c = [1, 2, 3, 4, 5]
    class TEST():
    c = [5, 2, 3, 4, 5] ## class variable (TEST.c)
    def __init__(self):
    self.c = [1, 2, 3, 4, 5] ## instance variable (a.c)

    def add(self, c):
    self.c[0] = 15 ## instance variable
    TEST.c[0] = -1 ## class variable
    c[0] = 100 ## variable/list
    return c

    a = TEST()
    c = a.add(c)
    print( c, a.c, TEST.c )
     
    David, Feb 24, 2012
    #4
  5. On Fri, 24 Feb 2012 10:08:43 -0800, David wrote:

    > Your code updated to show the difference between a variable, a class
    > variable, and an instance variable.


    The preferred terms in Python circles are class and instance
    *attributes*, not variables.

    An integer variable is a variable holding an integer.

    A string variable is a variable holding a string.

    A list variable is a variable holding a list.

    Therefore a class variable is a variable holding a class, and an instance
    variable is a variable holding an instance.

    Yes, in Python, classes and types are first-class objects (pun not
    intended), and it is quite common to store them in variables:

    for cls in (int, float, Decimal, Fraction, myint, myfloat):
    do_something_with(cls)


    Other languages may choose to use illogical terminology if they choose.



    --
    Steven
     
    Steven D'Aprano, Feb 24, 2012
    #5
  6. On 24/02/2012 22:25, Steven D'Aprano wrote:
    > On Fri, 24 Feb 2012 10:08:43 -0800, David wrote:
    >
    >> Your code updated to show the difference between a variable, a class
    >> variable, and an instance variable.

    >
    > The preferred terms in Python circles are class and instance
    > *attributes*, not variables.
    >
    > An integer variable is a variable holding an integer.
    >
    > A string variable is a variable holding a string.
    >
    > A list variable is a variable holding a list.
    >
    > Therefore a class variable is a variable holding a class, and an instance
    > variable is a variable holding an instance.
    >
    > Yes, in Python, classes and types are first-class objects (pun not
    > intended), and it is quite common to store them in variables:
    >
    > for cls in (int, float, Decimal, Fraction, myint, myfloat):
    > do_something_with(cls)
    >
    >
    > Other languages may choose to use illogical terminology if they choose.
    >


    Surely you mean names, not variables? :)

    --
    Cheers.

    Mark Lawrence.
     
    Mark Lawrence, Feb 25, 2012
    #6
  7. On Sat, 25 Feb 2012 00:39:39 +0000, Mark Lawrence wrote:

    > On 24/02/2012 22:25, Steven D'Aprano wrote:
    >> On Fri, 24 Feb 2012 10:08:43 -0800, David wrote:
    >>
    >>> Your code updated to show the difference between a variable, a class
    >>> variable, and an instance variable.

    >>
    >> The preferred terms in Python circles are class and instance
    >> *attributes*, not variables.
    >>
    >> An integer variable is a variable holding an integer.
    >>
    >> A string variable is a variable holding a string.
    >>
    >> A list variable is a variable holding a list.
    >>
    >> Therefore a class variable is a variable holding a class, and an
    >> instance variable is a variable holding an instance.
    >>
    >> Yes, in Python, classes and types are first-class objects (pun not
    >> intended), and it is quite common to store them in variables:
    >>
    >> for cls in (int, float, Decimal, Fraction, myint, myfloat):
    >> do_something_with(cls)
    >>
    >>
    >> Other languages may choose to use illogical terminology if they choose.
    >>
    >>

    > Surely you mean names, not variables? :)


    Well yes, I do, but the idea of classes being first class objects is
    radical enough to some people without also introducing them to the idea
    that there are no variables at all!

    I'm very aware that name binding is not quite the same as variables in
    some other languages, but the difference is subtle and doesn't mean that
    the term "variable" is owned by Pascal- or C-like languages. It just
    means that, like most computer science terms, "variable" has subtle
    differences from implementation to implementation.



    --
    Steven
     
    Steven D'Aprano, Feb 25, 2012
    #7
  8. On Sun, 26 Feb 2012 19:47:49 +1100, Ben Finney wrote:

    >> An integer variable is a variable holding an integer. A string variable
    >> is a variable holding a string. A list variable is a variable holding a
    >> list.

    >
    > And Python has none of those. Its references don't “hold†anything.


    Ah, but they do. Following the name binding:

    x = 1

    the name "x" now holds a reference to an int, or if you want to cut out
    one layer of indirection, the name "x" holds an int. That is to say, the
    value associated with the name "x" is an int.

    I don't believe this is a troublesome concept.


    > I appreciate that you think “variable†is a useful term in Python, but
    > this kind of mangling of the concept convinces me that it's not worth
    > it.


    I'm not sure that there is any mangling here. Or at least, the concept is
    only mangled if you believe that Pascal- or C-like variables (named
    memory locations) are the one true definition of "variable". I do not
    believe this.

    Words vary in their meanings, pun not intended, and in the same way that
    the semantics of classes in (say) Java are not identical to the semantics
    of classes in Python, so I think that it is perfectly reasonable to talk
    about Python having variables, implemented using bindings to objects in a
    namespace, even though the semantics of Python variables is slightly
    different from that of C variables.

    Fundamentally, a variable is a name associated with a value which can
    vary. And Python name bindings meet that definition no less than C fixed
    memory locations.


    > Python doesn't have variables, and even if you want to say “variablesâ€
    > when you mean “referencesâ€, there's no such thing as a “string variableâ€
    > etc. in Python. References don't have types, so its needlessly confusing
    > to perpetuate that kind of thinking.


    But objects have types, and it makes sense to state that the type of the
    name is the type of the object bound to that name, at least for the
    duration of the binding. That's exactly what we write in Python:

    type(x)

    tells us the type of x, whatever x happens to be. There's no implication
    that it is the type of the *name* x, since names are not typed.

    More importantly, while Python doesn't have static types, in real code,
    names generally are expected to be bound to objects of a particular type
    (perhaps a duck-type, but still a type). It is rare to have code
    including a name bound to *anything at all* -- the main counter-example I
    can think of is the id() function. Generally, names are expected to be
    bound to a specific kind of value: perhaps as specific as "a string", or
    as general as "an iterable", or "anything with a __add__ method", but
    nevertheless there is the expectation that if the name is bound to
    something else, you will get an error. A compile time error in C, a
    runtime error in Python, but either way, the expectation is that you get
    an error.

    In an example like this:

    def spam(some_string):
    return some_string.upper() + "###"

    I maintain that it is reasonable to say that "some_string is a string
    variable", since that expresses the programmer's intention that
    some_string should be bound to string objects (modulo duck-typing). If
    Python were statically typed, then passing some_string=42 would cause a
    compile-time error. In Python, you get a runtime error instead. I don't
    believe this invalidates the idea that some_string is intended to be a
    string.

    Or to make this painfully complete: some_string is a name linked to a
    value which can vary (hence a variable) intended to be limited to strings
    (hence a string variable). Python may not enforce this to the same extent
    as C or Haskell or Pascal, but the concept still holds.


    --
    Steven
     
    Steven D'Aprano, Feb 26, 2012
    #8
  9. On Tue, 28 Feb 2012 22:36:56 +1100, Ben Finney wrote:

    > Steven D'Aprano <> writes:
    >
    >> On Sun, 26 Feb 2012 19:47:49 +1100, Ben Finney wrote:
    >>
    >> >> An integer variable is a variable holding an integer. A string
    >> >> variable is a variable holding a string. A list variable is a
    >> >> variable holding a list.
    >> >
    >> > And Python has none of those. Its references don't “hold†anything.

    >>
    >> Ah, but they do. Following the name binding:
    >>
    >> x = 1
    >>
    >> the name "x" now holds a reference to an int, or if you want to cut out
    >> one layer of indirection, the name "x" holds an int. That is to say,
    >> the value associated with the name "x" is an int.

    >
    > Names don't hold anything. Not in natural language, and not in Python.


    I don't agree, I think the analogy of "holding on to", or "holding",
    works well for names in this context. A *binding* (the term you prefer)
    refers to the process of *tying* two objects together with rope, string,
    or twine such that they *hold fast*. If names don't hold values, neither
    can they be bound.

    I would be surprised if many programmers, whether experienced or not, or
    even non-programmers, failed to grasp the concept of a name "holding" a
    value. (And I point out that to *grasp a concept* is also to hold on to
    it. We hold our loved ones dear even when they are on the other side of
    the world, we hold these truths to be self-evident, and we don't hold
    with that sort of behaviour -- surely we are capable of holding onto the
    idea that names can hold values?)

    But rather than spend any more time trying to convince you to hold a
    different opinion, I will accept your criticism and rephrase my earlier
    statement:

    A string variable is a symbolic identifier given to a value and capable
    of being varied, which is given to a value which is a string.

    Python has these -- it has names, which are symbolic identifiers given to
    values, and those name:value bindings are capable of varying. It has
    strings. And you can bind names to strings. Ergo, it has string variables.

    I acknowledge that when I say "string variable", I mean a variable whose
    value is a string *at this moment*, I don't mean a variable which is
    prohibited by the compiler from taking a non-string value.

    To the extent that careless use of the term variable may confuse the
    naive reader who assumes that Python is just like Pascal (or any other
    statically typed language), it is sometimes useful to emphasis the
    differences by talking about "name bindings". But sometimes it is useful
    to emphasis the similarities, in which case "name binding" is obfuscatory
    and "variable" is perfectly reasonable.



    --
    Steven
     
    Steven D'Aprano, Feb 28, 2012
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Èý¹â
    Replies:
    1
    Views:
    578
    William F. Robertson, Jr.
    Jul 29, 2003
  2. Replies:
    0
    Views:
    5,141
  3. Anonymous
    Replies:
    3
    Views:
    535
    Ron Natalie
    Aug 18, 2003
  4. Jason Heyes
    Replies:
    1
    Views:
    454
    Woebegone
    Nov 19, 2004
  5. Petter Reinholdtsen
    Replies:
    9
    Views:
    4,376
    Howard
    Nov 29, 2004
Loading...

Share This Page