Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #76640 > unrolled thread

what is the difference between name and _name?

Started byluofeiyu <elearn2014@gmail.com>
First post2014-08-20 15:16 +0800
Last post2014-08-20 14:18 +0200
Articles 8 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  what is the difference between name and _name? luofeiyu <elearn2014@gmail.com> - 2014-08-20 15:16 +0800
    Re: what is the difference between name and _name? Steven D'Aprano <steve@pearwood.info> - 2014-08-20 08:49 +0000
      Re: what is the difference between name and _name? luofeiyu <elearn2014@gmail.com> - 2014-08-20 19:41 +0800
        Re: what is the difference between name and _name? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-21 01:26 +1000
          Re: what is the difference between name and _name? luofeiyu <elearn2014@gmail.com> - 2014-08-21 10:20 +0800
          Re: what is the difference between name and _name? Chris Angelico <rosuav@gmail.com> - 2014-08-21 13:10 +1000
          Re: what is the difference between name and _name? luofeiyu <elearn2014@gmail.com> - 2014-08-22 14:37 +0800
      Re: what is the difference between name and _name? "Frank Millman" <frank@chagford.com> - 2014-08-20 14:18 +0200

#76640 — what is the difference between name and _name?

Fromluofeiyu <elearn2014@gmail.com>
Date2014-08-20 15:16 +0800
Subjectwhat is the difference between name and _name?
Message-ID<mailman.13190.1408519045.18130.python-list@python.org>
When i learn property in python , i was confused by somename and _somename,what is the difference between them?

class Person(object):
     def __init__(self, name):
         self._name = name
     def getName(self):
         print('fetch....')
         return self._name
     def setName(self, value):
         print('change...')
         self._name = value
     def delName(self):
         print('remove....')
         del self._name
     name = property(getName, setName, delName, "name property docs")


>>> bob._name
'Bob'
>>> pt=Person("peter")
>>> pt.name
fetch....
'peter'
>>> pt._name
'peter'
>>> pt.name="tom"
change...
>>> pt._name="tom"
>>> pt._name
'tom'
>>> pt.name
fetch....
'tom'

[toc] | [next] | [standalone]


#76644

FromSteven D'Aprano <steve@pearwood.info>
Date2014-08-20 08:49 +0000
Message-ID<53f46100$0$29884$c3e8da3$5496439d@news.astraweb.com>
In reply to#76640
On Wed, 20 Aug 2014 15:16:56 +0800, luofeiyu wrote:

> When i learn property in python , i was confused by somename and
> _somename,what is the difference between them?

One name starts with underscore, the other does not. In names, an 
underscore is just a letter with no special meaning:

foo, bar, foo_bar, spam, spam2, spam_with_eggs ...

But Python has some naming conventions:

(1) Names with TWO underscores at the start and end of the name are 
reserved for Python: __dict__ __add__ __str__ etc. all have special 
meaning to Python.

(2) Names with ONE leading underscore are intended as "private" variables 
or names, the caller should not use it.

So in this example:

> class Person(object):
>      def __init__(self, name):
>          self._name = name
       [...]
>      name = property(getName, setName, delName, "name property docs")

(1) __init__ is a "dunder" (Double UNDERscore) name, and is special to 
Python. It is used for the initialiser method;

(2) _name is a single underscore "private" attribute, only the Person 
class is supposed to use it; and

(3) name is the public attribute that other classes or functions are 
permitted to use.


Unless the documentation for the class or library says different, you 
should ignore any _single underscore methods and attributes. They are 
private, and subject to change without warning.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#76657

Fromluofeiyu <elearn2014@gmail.com>
Date2014-08-20 19:41 +0800
Message-ID<mailman.13201.1408534898.18130.python-list@python.org>
In reply to#76644
So in this example:
>> class Person(object):
>>       def __init__(self, name):
>>           self._name = name
>         [...]
>>       name = property(getName, setName, delName, "name property docs")
>
>
> (3) name is the public attribute that other classes or functions are
> permitted to use.
>
>
> problem 1:  there is no self.name =  something in the defination ,why i can get bob.name?
>
>
class Person(object):
     def __init__(self, name):
         self._name = name
     def getName(self):
         print('fetch....')
         return self._name
     def setName(self, value):
         print('change...')
         self._name = value
     def delName(self):
         print('remove....')
         del self._name
     name = property(getName, setName, delName, "name property docs")

 >>> bob=Person("dear bob")
 >>> bob._name  # there is a defination in class Person ,self._name = 
name ,when we initial it ,we can get bob._name
'dear bob'
 >>> bob.name  #there is no defination in class Person ,self.name=name 
,why we can get the value of bob.name?
fetch....
'dear bob'


problem 2: what is the meaning of

name = property(getName, setName, delName, "name property docs")    ?

why i can not write  _name = property(getName, setName, delName, "name property docs") ?


  class Person(object):

     def __init__(self, name):

         self._name = name

     def getName(self):

         print('fetch....')

         return self._name

     def setName(self, value):

         print('change...')

         self._name = value

     def delName(self):

         print('remove....')

         del self._name

     _name = property(getName, setName, delName, "name property docs")

bob=Person("dear bob")

I got error from the codes:

   File "<stdin>", line 9, in setName
   File "<stdin>", line 8, in setName
RuntimeError: maximum recursion depth exceeded while calling a Python object

[toc] | [prev] | [next] | [standalone]


#76669

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-08-21 01:26 +1000
Message-ID<53f4be1f$0$29978$c3e8da3$5496439d@news.astraweb.com>
In reply to#76657
luofeiyu wrote:

> So in this example:

>>> class Person(object):
>>>       def __init__(self, name):
>>>           self._name = name
>>         [...]
>>>       name = property(getName, setName, delName, "name property docs")
>>
>>
>> (3) name is the public attribute that other classes or functions are
>> permitted to use.
>>
>
> problem 1:  there is no self.name =  something in the defination ,why i
> can get bob.name?

Do you understand how classes and instances work in Python? This part has
nothing to do with properties, it is just ordinary attribute access.

Here is a simple class:

class Person(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return "Person(%r)" % self.name
    def show(self):
        print(self)


And in use:

py> instance = Person('Bob')  # Variable is called "instance".
py> instance.show()
Person('Bob')
py> print(Bob.name)  # Fails, because no variable called Bob.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Bob' is not defined
py> instance.name
'Bob'

Dot . is just used for attribute lookup, regardless of whether it is an
instance attribute, class attribute, method or property.



Here is your example:

> class Person(object):
>      def __init__(self, name):
>          self._name = name
>      def getName(self):
>          print('fetch....')
>          return self._name
>      def setName(self, value):
>          print('change...')
>          self._name = value
>      def delName(self):
>          print('remove....')
>          del self._name
>      name = property(getName, setName, delName, "name property docs")
> 
>  >>> bob=Person("dear bob")
>  >>> bob._name  # there is a defination in class Person ,self._name =
> name ,when we initial it ,we can get bob._name
> 'dear bob'
>  >>> bob.name  #there is no defination in class Person ,self.name=name
> ,why we can get the value of bob.name?
> fetch....
> 'dear bob'

The line "name = property(...)" is a definition in class Person. Here is
another example:

class X(object):
    attribute = "an attribute bound to the class"
    def method(self):
        print("Methods are bound to the class")
    spam = "Spam spam spam SPAM!!!"

x = X()  # Creates an instance.

x.attribute
=> returns "an attribute bound to the class"

x.spam
=> returns "Spam spam spam SPAM!!!"

x.method()
=> prints "Methods are bound to the class"


In all three cases, the lookup x.<something> does not find any attribute
bound to the instance x, so it continues searching for an attribute bound
to the class, where it finds one.

We can hide the class attribute:

x.attribute = "This is on the instance."
x.attribute
=> returns "This is on the instance."
X.attribute  # Look up on the class
=> returns "an attribute bound to the class"

When you do an attribute lookup instance.name, Python does something like
this (except a bit more complicated):

- calls __getattribute__, if it is defined

- if not, search the instance __dict__ (instance attributes, self.attribute)

- if still not found, search the class __dict__ (class attribute)

- if still not found, search all the superclasses

- if still not found, call __getattr__, if it is defined

- otherwise, raise AttributeError


Properties are attached to the class:

class Person(object):
    ...
    name = property(...)  # on the class, not the instance


If you attach them to the instance, they won't work:

# Don't do this!
class Person(object):
    def __init__(self):
        self.name = property(...)  # Doesn't work.


When Python retrieves the property, it calls either the getter, setter or
deleter method, depending on which is needed.



> problem 2: what is the meaning of
> 
> name = property(getName, setName, delName, "name property docs")    ?

The property() function takes up to four arguments, and returns a Property
object, which then gets bound to the attribute "name".


> why i can not write  _name = property(getName, setName, delName, "name
> property docs") ?

Because you will have infinite recursion.

When you look up instance._name:

10 Python finds the property _name
20 Python retrieves the getter, getName
30 Python runs the getName() method
40 which looks up self._name
50 go to 10

and you get a recursion error.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#76690

Fromluofeiyu <elearn2014@gmail.com>
Date2014-08-21 10:20 +0800
Message-ID<mailman.13226.1408587631.18130.python-list@python.org>
In reply to#76669
one more question,how can i get the doc info?

class Person(object):
     def __init__(self, name):
         self._name = name
     def getName(self):
         print('fetch....')
         return self._name
     def setName(self, value):
         print('change...')
         self._name = value
     def delName(self):
         print('remove....')
         del self._name
     name = property(getName, setName, delName, "name property docs")

Person("bob").name.doc
Person("bob").name.__doc__
Person("bob")._name.doc
Person("bob")._name.__doc__

all the expressions can not get the info "name property docs" ?how can i 
get it?

[toc] | [prev] | [next] | [standalone]


#76693

FromChris Angelico <rosuav@gmail.com>
Date2014-08-21 13:10 +1000
Message-ID<mailman.13227.1408590657.18130.python-list@python.org>
In reply to#76669
On Thu, Aug 21, 2014 at 12:20 PM, luofeiyu <elearn2014@gmail.com> wrote:
>
> all the expressions can not get the info "name property docs" ?how can i get
> it?

>>> Person.name.__doc__
'name property docs'

It's an attribute of the property, not of the result.

ChrisA

[toc] | [prev] | [next] | [standalone]


#76777

Fromluofeiyu <elearn2014@gmail.com>
Date2014-08-22 14:37 +0800
Message-ID<mailman.13275.1408689455.18130.python-list@python.org>
In reply to#76669
I fix a mistake in Steven D'Aprano interpretation.

class Person(object):
      def __init__(self, name):
          self._name = name
      def getName(self):
          print('fetch....')
          return self._name
      def setName(self, value):
          print('change...')
          self._name = value
      def delName(self):
          print('remove....')
          del self._name
      _name = property(getName, setName, delName, "name property docs")


x=Person("peter")

It can not initinalize.
   File "<stdin>", line 9, in setName
   File "<stdin>", line 8, in setName
RuntimeError: maximum recursion depth exceeded while calling a Python 
object.

Steven D'Aprano interpretation:

10 Python finds the property _name
20 Python retrieves the getter, getName
30 Python runs the getName() method
40 which looks up self._name
50 go to 10

the right interpretation according to the error message:


10 python call __init__ method. self._name = name
20 python call setName method,
          print('change...')
          self._name = value
30 from self._name = value ,python call call setName method again

then we get a recursion error.
>> why i can not write  _name = property(getName, setName, delName, "name
>> property docs") ?
> Because you will have infinite recursion.
>
> When you look up instance._name:
>
> 10 Python finds the property _name
> 20 Python retrieves the getter, getName
> 30 Python runs the getName() method
> 40 which looks up self._name
> 50 go to 10
>
> and you get a recursion error.
>
>
>

[toc] | [prev] | [next] | [standalone]


#76661

From"Frank Millman" <frank@chagford.com>
Date2014-08-20 14:18 +0200
Message-ID<mailman.13204.1408537124.18130.python-list@python.org>
In reply to#76644
"luofeiyu" <elearn2014@gmail.com> wrote in message 
news:53F48957.8020700@gmail.com...
> So in this example:
>>> class Person(object):
>>>       def __init__(self, name):
>>>           self._name = name
>>         [...]
>>>       name = property(getName, setName, delName, "name property docs")
>>
>>
>> (3) name is the public attribute that other classes or functions are
>> permitted to use.
>>
>>
>> problem 1:  there is no self.name =  something in the defination ,why i 
>> can get bob.name?
>>
>>

I also found it confusing at first, but reading the docs and trying out the 
examples at the interpreter prompt helped a lot.

Here is the relevant doc page -

    https://docs.python.org/3/library/functions.html#property

If you really want to know what goes on under the hood, Google turned up 
this in-depth explanation -

    http://stackoverflow.com/questions/17330160/how-does-the-property-decorator-work

HTH

Frank Millman


[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web