Почему «приватные» методы Python на самом деле не приватны?

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DuplicateWord {

    public static void main(String[] args) {
        String para = "this is what it is this is what it can be";
        List < String > paraList = new ArrayList < String > ();
        paraList = Arrays.asList(para.split(" "));
        System.out.println(paraList);
        int size = paraList.size();

        int i = 0;
        Map < String, Integer > duplicatCountMap = new HashMap < String, Integer > ();
        for (int j = 0; size > j; j++) {
            int count = 0;
            for (i = 0; size > i; i++) {
                if (paraList.get(j).equals(paraList.get(i))) {
                    count++;
                    duplicatCountMap.put(paraList.get(j), count);
                }

            }

        }
        System.out.println(duplicatCountMap);
        List < Integer > myCountList = new ArrayList < > ();
        Set < String > myValueSet = new HashSet < > ();
        for (Map.Entry < String, Integer > entry: duplicatCountMap.entrySet()) {
            myCountList.add(entry.getValue());
            myValueSet.add(entry.getKey());
        }
        System.out.println(myCountList);
        System.out.println(myValueSet);
    }

}

Вход: это именно то, что это может быть

Выход:

[это, есть, что, это, есть, это, есть, что, это, может быть]

{can = 1, what = 2, be = 1, this = 2, is = 3, it = 2}

[1, 2, 1, 2, 3, 2]

[can, what, be, this, is, it]

610
задан Stefan van den Akker 28 December 2013 в 13:47
поделиться

9 ответов

Скремблирование имени используется, чтобы гарантировать, чтобы подклассы случайно не переопределяли закрытые методы и атрибуты их суперклассов. Это не разработано для предотвращения преднамеренного доступа снаружи.

, Например:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

, Конечно, это ломается, если два различных класса имеют то же имя.

558
ответ дан Alya 28 December 2013 в 13:47
поделиться

От http://www.faqs.org/docs/diveintopython/fileinfo_private.html

Строго говоря, закрытые методы доступны вне своего класса, просто не легкодоступны. Ничто в Python не является действительно частным; внутренне, названия закрытых методов и атрибутов искажаются и не искажаются на лету, чтобы заставить их казаться недоступными своими именами. Можно получить доступ __ метод синтаксического анализа класса MP3FileInfo именем _MP3FileInfo __ синтаксический анализ. Подтвердите, что это интересно, затем обещайте никогда не сделать это в реальном коде. Закрытые методы являются частными по причине, но как много других вещей в Python, их частность является в конечном счете вопросом соглашения, не вызывают.

140
ответ дан xsl 28 December 2013 в 13:47
поделиться

Это не похоже на Вас, absolutly не может обойти частность участников ни на каком языке (адресная арифметика с указателями в C++, Отражения в.NET/Java).

Дело в том, что Вы получаете ошибку, при попытке назвать закрытый метод случайно. Но если Вы хотите выстрелить себе в ногу, идти вперед и сделать это.

Редактирование: Вы не пытаетесь защитить свой материал инкапсуляцией OO, не так ли?

32
ответ дан Maximilian 28 December 2013 в 13:47
поделиться

Наиболее часто используемая фраза, "мы все соглашаемся взрослые здесь". Путем предварительного ожидания (скрываются) одинарное подчеркивание (не представляют) или двойное подчеркивание, Вы говорите пользователю Вашего класса о предположении участника, чтобы быть 'частными' в некотором роде. Однако Вы доверяете всем остальным, чтобы вести себя ответственно и уважать это, если у них нет неопровержимого довода не к (например, отладчики, кодируйте завершение).

, Если у Вас действительно должно быть что-то, что является частным, тогда можно реализовать его в расширении (например, в C для CPython). В большинстве случаев, однако, Вы просто изучаете Pythonic способ сделать вещи.

87
ответ дан Tony Meyer 28 December 2013 в 13:47
поделиться

Подобное поведение существует, когда названия атрибута модуля начинаются с одинарного подчеркивания (например, _foo).

атрибуты Модуля, названные как таковыми, не будут скопированы в модуль импорта при использовании from* метод, например:

from bar import *

Однако это - соглашение и не ограничение языка. Это не частные атрибуты; на них может сослаться и управлять любое средство импорта. Некоторые утверждают, что из-за этого, Python не может реализовать истинную инкапсуляцию.

12
ответ дан Ross 28 December 2013 в 13:47
поделиться

class.__stuff соглашение о присвоении имен сообщает программисту, он не предназначен для доступа __stuff снаружи. Искажение имени делает его вряд ли, любой сделает это случайно.

Правда, все еще можно работать вокруг этого, это еще легче, чем на других языках (какие BTW также позволяют Вам сделать это), но никакой Python программист не сделал бы это, если он заботится об инкапсуляции.

12
ответ дан Nickolay 28 December 2013 в 13:47
поделиться

Это - только одно из тех проектных решений языка. На некотором уровне они выравниваются по ширине. Они делают его так, необходимо пойти довольно далеко из способа попытаться назвать метод, и если Вам действительно нужен он, что плохо, у Вас должно быть довольно серьезное основание!

рычаги Отладки и тестирование приходят на ум как возможные приложения, использованные ответственно, конечно.

12
ответ дан Peter Mortensen 28 December 2013 в 13:47
поделиться

Когда я впервые пришел с Java на Python, я ненавидел это. Это меня до смерти напугало.

Сегодня, возможно, это единственное , что я люблю в Python больше всего .

Мне нравится быть на платформе, где люди доверяют друг другу и не чувствуют необходимости строить непроницаемые стены вокруг своего кода. В сильно инкапсулированных языках, если в API есть ошибка, и вы поняли, что идет не так, вы все равно не сможете работать с ней, потому что нужный метод является частным. В Python отношение таково: "конечно". Если вы думаете, что понимаете ситуацию, возможно, вы даже читали ее, то все, что мы можем сказать, это "удачи!"

Помните, что инкапсуляция даже не имеет слабого отношения к "безопасности", или к тому, чтобы держать детей подальше от газона. Это всего лишь еще один шаблон, который следует использовать для того, чтобы сделать кодовую базу более понятной.

.
160
ответ дан 22 November 2019 в 21:53
поделиться

Пример частной функции

import re
import inspect

class MyClass :

    def __init__(self) :
        pass

    def private_function ( self ) :
        try :
            function_call = inspect.stack()[1][4][0].strip()

            # See if the function_call has "self." in the begining
            matched = re.match( '^self\.', function_call )
            if not matched :
                print 'This is Private Function, Go Away'
                return
        except :
            print 'This is Private Function, Go Away'
            return

        # This is the real Function, only accessible inside class #
        print 'Hey, Welcome in to function'

    def public_function ( self ) :
        # i can call private function from inside the class
        self.private_function()

### End ###
204
ответ дан 22 November 2019 в 21:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: