Имя класса и имя файла

Я из Java. Я просматриваю официальные учебные пособия по Python, но не могу найти информацию об именах и классах исходных файлов Python.

В Java имя файла совпадает с именем основного класса плюс расширение .java. В питоне в чем дело? В примерах официальных руководств они пишут несколько классов и не упоминают имя файла. Я немного потерян.

У меня есть имя файла test_pie.py. Содержание это-

class ListTest:

    list1 = [2, 'a', 'ab', 'c', 'aa', 0]

    list2 = ['b', list1[-2:-5]] 

    def PrintList(self):
        print list1
        print list2

Для списка1 и списка2: я получаю-

Неопределенная переменная: list1 list Найдено по адресу: test_pie

Неопределенная переменная: список list2 Найдено по адресу: test_pie


person Sumon Tagoe    schedule 09.07.2011    source источник
comment
Кажется, у вас здесь несколько вопросов. На какой из них вы хотите получить ответ?   -  person Ignacio Vazquez-Abrams    schedule 10.07.2011
comment
Я поместил фрагмент кода, так как думал, что это вызвано несоответствием имени файла и имени класса. После редактирования я увидел ваш ответ (это было быстро). Мне понравился твой ответ. Это было ясно.   -  person Sumon Tagoe    schedule 10.07.2011
comment
Фрагмент кода не имеет ничего общего ни с одним из поставленных перед ним вопросов.   -  person Ignacio Vazquez-Abrams    schedule 10.07.2011


Ответы (3)


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

Содержимое файла не ограничено одним классом, и мало кто налагает на себя такое ограничение. Python — это не только объектно-ориентированный язык, у вас могут и должны быть свободные функции, когда это целесообразно, а модули рассматриваются на один уровень выше классов в организации кода — если несколько классов тесно связаны, они, вероятно, должны находиться в одном модуле.

Ваш пример кода/проблемы не связан с этим, это вопрос объема внутри данного файла. Классы имеют свою собственную область видимости, но вы не можете и не должны использовать переменные класса содержащего класса в таких методах (напрямую) - это заставит код не обращать внимания на новое значение, установленное в подклассе. Вместо этого вы либо используете методы класса (кстати, вы должны прочитать http://dirtsimple.org/2004/12/python-is-not-java.html) или использовать тот факт, что экземпляры наследуют все члены класса и просто добавляют к ним префикс self..

person Community    schedule 09.07.2011
comment
Экземпляры не наследуют атрибуты (название Pythonic для членов) класса; скорее, попытка найти атрибут в объекте также попытается найти в классе, если у объекта его нет. Это означает, что если list1 используется таким образом, он будет эффективно разделяться между экземплярами класса. Остерегаться. - person Karl Knechtel; 10.07.2011
comment
@Karl: Да, это, конечно, то, что я имел в виду, но не смог правильно выразить. Благодарю за разъяснение. - person ; 10.07.2011

В Python один файл представляет собой модуль, аналогичный пространству имен в Java, поэтому все классы для одного пространства имен будут находиться в одном файле.

person hammar    schedule 09.07.2011
comment
Я вызвал обратную реакцию... когда обнаружил, что то, что я считал классом, оказалось просто модулем. Мир Python снова становится лучшей практикой программирования... :( - person mimic; 28.08.2018

Ява - это не Питон. Питон это не Ява. Вы только что обнаружили здесь много различий; больше, чем вы ожидаете.

В Java имя файла совпадает с именем основного класса плюс расширение .java. В питоне в чем дело?

Наоборот: имя файла не обязательно совпадает с чем-либо.

В примерах официальных руководств они пишут несколько классов и не упоминают имя файла. Я немного потерян.

Потому что это не имеет значения. (Обратите внимание, что в Java у вас все еще может быть более одного класса в файле, если только один с соответствующим именем — public. В Python public на самом деле не существует.)

Для списка1 и списка2: я получаю-

Неопределенная переменная: list1 list Найдено по адресу: test_pie

Неопределенная переменная: список list2 Найдено по адресу: test_pie

Это связано с тем, что эти атрибуты (то, что вы бы назвали «полями» в Java) принадлежат классу, а не объекту.

Метод (то же имя, что и в Java) по-прежнему «принадлежит» классу в Python-думании, но доступ к нему осуществляется через объект. Вот почему вам нужен явный параметр self для методов Python: потому что my_object.do_something(x, y, z) неявно переводится в MyClass.do_something(my_object, x, y, z) (более или менее; за кулисами есть некоторая хитрость с «привязкой», которая позволяет вам рассматривать my_object.do_something как объект. Да, в Python , все является объектом, даже функции. А вы думали, что Java — это объектно-ориентированное программирование. Ха.)

Вы по-прежнему можете получить доступ к атрибутам класса через объект, если вы укажете Python, где его искать. Внутри PrintList, list1 и list2 не находятся в области действия, потому что Python действительно имеет только две области действия: локальную и глобальную. Но self находится в области (это параметр, поэтому он находится в локальной области), и вы можете получить доступ к self.list1, поскольку поиск атрибута объекта в Python возвращается к атрибутам класса, если атрибут объекта отсутствует. (На самом деле все гораздо сложнее: есть пара различных хуков с именами специальных методов, которые вы можете вставить в процесс, не говоря уже о том, как обрабатывается наследование.)

Итак, вы, вероятно, сейчас задаетесь вопросом, как получить атрибуты в реальном объекте Python, а не в его классе. Ответ: вы просто назначаете их. Если вы не ставите никаких ограничений, то вы можете назначить их в любое время, с любым именем. Объект в основном просто словарь. Если вы знакомы с Java*script* (язык, совершенно не связанный с Java), то он работает примерно так же. Однако, чтобы контролировать это безумие, обычно назначают начальные значения атрибутов в методе со специальным именем __init__, который автоматически вызывается (если он найден) сразу после создания объекта (но это не). конструктор в обычном смысле; эту роль играет __new__, но на самом деле он почти никогда не нужен в Python), а затем только переназначать атрибуты, которые были установлены там, а не создавать новые.

Вы можете установить ограничения, если у вас есть класс нового стиля (автоматический в 3.x; в 2.x вы должны наследовать хотя бы косвенно от встроенного типа object), указав значение для специально названного атрибута класса называется __slots__. Это должен быть список строк, которые являются допустимыми именами идентификаторов. При этом Python будет (а) использовать информацию для оптимизации своего внутреннего хранилища данных для объектов; (b) запретить вам добавлять к объекту атрибуты с другими именами; (c) запретить создание специального атрибута __dict__ для экземпляров объекта, который представляет собой словарь, отображающий имена атрибутов в значения атрибутов. (А вы думали, что Java поддерживает отражение. Ха.) Он не автоматически присваивает значения именованным атрибутам; попытка получить к ним доступ до того, как они были назначены, приведет к raise AttributeError.

person Karl Knechtel    schedule 10.07.2011