How do I set a private property in Python? And is there a protected property?

Asked

Viewed 2,743 times

5

I come from PHP. In it, when we want to define a property of a class as private we add the keyword private in his statement.

Example:

class StackOverflow extends StackExchange
{
    private $language = 'en'; // privado, só pode ser acessado via Accessor!

    public function __construct($language === null){
            
            if ($language !== null) {
                $this->language = $language;
            }

    }

    public function getLanguage()
    {
        return $this->language;
    }
}

Now I’d like to know how to do it in Python. How to define private property in this example below.

class StackExchange(object):
    def __init__(self):
        pass

class StackOverflow(StackExchange):

    language = 'en' // quero que seja privado ou protegido!
    
    def __init__(self, language = None):
        if language is not None:
            self.language = language


sopt = StackOverflow('pt')
sopt.language // retorna o valor, mas quero utilizar um Accessor ao invés disso
            

Another thing: In PHP, we use protected to define that the property cannot be accessed at the class instantiation, but can be accessed by itself and who inherits it.

You can do this in Python too?

2 answers

5

Python there is no this concept of private property.

Following the PEP 8 - Style Guide for Python Code, you can use the __ in front of a method like a convention. Remembering that your method will not be "private", but it would be a kind of convention for those who see your code to know that this method (or variable) should only be used in the parent class.

Follow an excerpt from PEP 0008:

If your class is intended to be subclassed, and you have Attributes that you do not want subclasses to use, consider naming them with double Leading underscores and no trailing underscores. This invokes Python’s name mangling Algorithm, Where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain Attributes with the same name.

  • Still, you can access the variable through _StackOverflow__language, as in the example he asked for.

  • 4

    And always will. As said above, there is no concept of private variable.

  • Not a basic little cloister?

  • The closest you get to this is using __ in methods or variables. In this case they cannot be called publicly...

3


As @Joãopedroalves replies, there is no private property.

For protected properties, it would be a schema using modifiers @property and @nomedaproperty.setter:

class StackExchange(object):
    def __init__(self):
        pass

class StackOverflow(StackExchange):
    # Coloque sua variável dentro de __init__, o que "evita" que ela vire pública.
    # Ela ainda é acessível através de _StackOverflow__language.
    def __init__(self, language = None):
        self.__language = 'en'
        if language is not None:
            self.__language = language

    @property # Objeto.language cai aqui
    def language(self):
        return self.__language

    @language.setter # Objeto.language = 'pt' cai aqui
    def name(self, language):
        self.__language = language

Here you can test.

  • Just to refresh my brain? Are two underlines? type Len('__') 2?

  • Yes. Exactly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.