what is the difference between name and _name?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Aug 20 11:26:22 EDT 2014


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




More information about the Python-list mailing list