Пространство имен system c: System Пространство имен | Microsoft Docs

Содержание

использование пространства имен System; in Visual Studio 2013

Я пытаюсь использовать метод Console::SetCursorPosition (int, int) . Когда я добавляю строку using namespace System;, как показано в Примере C++ из предыдущей документации MSDN, я получаю ошибку "Error: name must be a namespace name" . Я пробую это уже пару часов, но, к сожалению, безуспешно. Я наткнулся на тонну документации для Visual Studio 2010 и 2012 годов, но очень мало для 2013 года. Ближайший я пришел-это lib-файлы в качестве входных данных компоновщика . Шаги 1-3 достаточно просты, но Шаг 4 мне не ясен: «Modify the Additional Dependencies property.». Глядя на то, что уже есть, кажется, что я могу просто добавить файл .lib. Но у меня нет System.lib.

Такой расстроенный, такой растерянный.

Как я могу использовать системное пространство имен в Visual Studio 2013 Update 4 для C++?

c++

visual-studio-2013

namespaces

using

Поделиться

Источник


Evorlor    

28 февраля 2015 в 03:39

3 ответа


  • отображение классов пространства имен в visual studio (C#)

    Я программист Java и только начинаю использовать Visual Studio для программирования C#. В Java IDE, например Eclipse, если я не знаю имени класса в пакете, я могу просто ввести точку (.) после имени пакета, тогда я получу список всех классов в этом пакете. Как я могу настроить visual studio, чтобы…

  • Остановите Visual Studio от размещения директив using вне пространства имен

    Есть ли параметр в Visual Studio (или Resharper), который позволяет указать, какие пространства имен должны быть по умолчанию и в какую область они помещаются? Например, значение по умолчанию для проекта MVC равно using System; using System.Collections.Generic; using System.Linq; using System.Web;…



6

Чтобы формализовать и расширить мой комментарий, класс Console и вообще пространство имен System являются частью фреймворка .NET.

В этом контексте вкладка «C++», включенная в страницу документации MSDN метода Console::SetCursorPosition(int, int) , фактически относится к языку C++/CLI . Язык C++/CLI отличается (хотя и намеренно похож) от языка C++. Соответственно, язык C++/CLI содержит различные конструкции, которые не распознаются набором инструментов компилятора C++, используемым при компиляции проектов Win32.

Другими словами, чтобы избавиться от ошибки "Error: name must be a namespace name" , вам нужно будет преобразовать ваш проект Win32 C++ в проект CLR. Самый простой способ сделать это-создать новый проект, выбрав один из шаблонов в разделе «Visual C++» / «CLR»:

Эквивалентом депенденций файлов .lib (относительно ваших Lib-файлов в качестве входной ссылки компоновщика ) проектов Win32 для проекта CLR будут ссылки assembly. Затем вы обычно добавляете эти ссылки assembly с «Add References» в разделе свойства проекта «Common Properties , References»:

Однако в вашем конкретном случае вы вполне можете обнаружить, что ссылка System assembly уже включена в шаблон проекта CLR.
Возможно, вы захотите проверить, как: добавить или удалить ссылки на MSDN для получения более подробной информации.

Наконец, если вы абсолютно этого хотите вручную преобразуйте существующий проект Win32, вам нужно будет установить свойства проекта «Common Language Runtime Support» под вкладками «General» и «C/C++ , Общие» в один из /clr , /clr:pure , /clr:safe или /clr:oldSyntax (в зависимости от ваших конкретных требований приложения; если вы просто играете, вы можете начать с /clr ) для всех конфигураций и платформ, а также указать целевую версию фреймворка .Net, непосредственно отредактировав .vcxproj (как указано в этом ответе )., Вам также все равно нужно будет добавить зависимости assembly, как и в случае с новым проектом Win32). проектный подход выше.

Поделиться


SleuthEye    

06 марта 2015 в 04:07



3

Вы должны установить Common Language Runtime Support (/clr) в свойствах конфигурации-общие:

А в свойствах конфигурации-C/C++-Общие сведения:

Поделиться


Saullo G. P. Castro    

05 июня 2017 в 12:58



1

У вас есть проект Win32 Console Application и вы используете пространство имен .NET . В консольном приложении Win32 в стандартной библиотеке имеется только пространство имен 4-5, включая std . Попробуйте using namespace std; наверху.

Поделиться


0x6773    

06 марта 2015 в 04:12


  • Отладка расширений пространства имен с помощью Visual Studio

    Каков наилучший способ отладки расширения пространства имен с помощью Visual Studio? Неудобно использовать regsvr32 для регистрации и отмены регистрации расширения и перезапуска Explorer для каждой сборки. Присоединение отладчика к расширению было бы хорошим преимуществом. Есть ли простой способ…

  • Как пропустить отладку всего пространства имен std в Visual C++ 2013?

    Я хочу пропустить отладку всего пространства имен std:: C++ по умолчанию, без изменения окна кода на std:: code , созданное Microsoft как xstring . Этот вопрос похож на : Как пропустить общие занятия в VS 2008 при входе? и автоматический пропуск функций STL во время отладки step-by-step в…


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

пространства имен: использование System & using System.IO

Итак, моя программа имеет эти 2 строки в начале using System; using System.IO; Вопрос: действительно ли второе утверждение необходимо для включения Sytem.IO методов и свойств в мой код? Похоже, что…

как добавить пространства имен в in visual studio c#

Как добавить пространства имен в visual studio, я имею в виду, что на java слово распространено, что (если вы предоставили ссылку на правильную библиотеку) вы можете добавить импорт в java…

Visual Studio 2013 конечной и Microsoft.VisualBasic.PowerPack

У меня есть решение в Windows формах C# и Visual Studio 2013 из Университета (dreamspark). Когда я пытаюсь запустить свое решение, я получаю ошибку: Ошибка 2 тип или имя пространства имен. ..

отображение классов пространства имен в visual studio (C#)

Я программист Java и только начинаю использовать Visual Studio для программирования C#. В Java IDE, например Eclipse, если я не знаю имени класса в пакете, я могу просто ввести точку (.) после имени…

Остановите Visual Studio от размещения директив using вне пространства имен

Есть ли параметр в Visual Studio (или Resharper), который позволяет указать, какие пространства имен должны быть по умолчанию и в какую область они помещаются? Например, значение по умолчанию для…

Отладка расширений пространства имен с помощью Visual Studio

Каков наилучший способ отладки расширения пространства имен с помощью Visual Studio? Неудобно использовать regsvr32 для регистрации и отмены регистрации расширения и перезапуска Explorer для каждой…

Как пропустить отладку всего пространства имен std в Visual C++ 2013?

Я хочу пропустить отладку всего пространства имен std:: C++ по умолчанию, без изменения окна кода на std:: code , созданное Microsoft как xstring . Этот вопрос похож на : Как пропустить общие…

Где находятся пространства имен в visual studio

Я новичок в Visual Studio и C#., я прошел через учебные пособия по C#, и все примеры программ, которые я прошел, были написаны внутри пространств имен. Но когда я использовал шаблон на Visual…

Как быстро разрешить пространства имен в Visual Studio 2015

Когда я набираю метод, для которого пространство имен не было импортировано, я получаю красное волнистое подчеркивание (он же волнистая красная линия), указывающее на ошибку. Используя Visual Studio…

Тип или имя пространства имен ‘Timers’ не существует в пространстве имен «system»

Я получаю эту ошибку, когда добавляю using System.Timers в visual studio 2013 using System.Timers; Ошибка: Тип или имя пространства имен ‘Timers’ не завершается в пространстве имен ‘System’…

Не можете собрать.Net core 2.2 проект? Тип или имя пространства имен ‘System’ не найдено

Сейчас я просто устанавливаю новейшее ядро ​​. Net.

PS C:\temp> dotnet --version
2.2.301

И я создал новый консольный проект.

PS C:\temp> dotnet new console

Добро пожаловать в.NET Core!

Узнайте больше о.NET Core: https://aka.ms/dotnet-docs Используйте «dotnet —help» для просмотра доступных команд или посетите страницу: https://aka.ms/dotnet-cli-docs

телеметрия

Инструменты.NET Core собирают данные об использовании, чтобы помочь нам улучшить ваш опыт. Данные являются анонимными и не содержат аргументов командной строки. Данные собираются Microsoft и передаются сообществу. Вы можете отказаться от телеметрии, установив переменную окружения DOTNET_CLI_TELEMETRY_OPTOUT в «1» или «true», используя вашу любимую оболочку.

Узнайте больше о.NET Core CLI Tools телеметрии: https://aka.ms/dotnet-cli-telemetry

ASP.NET Core

Успешно установлен сертификат разработки ASP.NET Core HTTPS. Чтобы доверять сертификату, запустите ‘dotnet dev-certs https —trust’ (только для Windows и macOS). Для установления доверия на других платформах обратитесь к документации конкретной платформы. Для получения дополнительной информации о настройке HTTPS см. https://go.microsoft.com/fwlink/?linkid=848054. Готовимся… Шаблон «Консольное приложение» создан успешно.

Обработка действий после создания… Запуск ‘dotnet restore’ на C:\temp\temp.csproj… Восстановление завершено за 190,58 мс для C: \ temp \ temp.csproj.

Восстановление прошло успешно.


Тем не мение, dotnet run получил следующую ошибку?

PS C: \ temp> dotnet run
C: \ Users \ wangyi \ AppData \ Local \ Temp \ 1 \.NETCoreApp, Version = v2.2.AssemblyAttributes.cs (4,20): ошибка CS0400: не удалось найти тип или имя пространства имен "Система" в глобальное пространство имен (вам не хватает ссылки на сборку?) [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(10,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp. csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(11,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(12,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(13,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(14,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(15,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2. 2\temp.AssemblyInfo.cs(16,12): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
C:\Users\wangyi\AppData\Local\Temp\1\.NETCoreApp,Version=v2.2.AssemblyAttributes.cs(4,71): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C: \ Temp\temp.csproj]
C:\Users\wangyi\AppData\Local\Temp\1\.NETCoreApp,Version=v2.2.AssemblyAttributes.cs(4,99): ошибка CS0246: не удалось найти тип или имя пространства имен FrameworkDisplayName (есть вы пропустили директиву using или ссылку на сборку?) [C:\temp\temp.csproj]
C:\Users\wangyi\AppData\Local\Temp\1\.NETCoreApp,Version=v2.2.AssemblyAttributes.cs(4,122): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(10,55): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2. 2\temp.AssemblyInfo.cs(11,61): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(12,59): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(13,68): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(14,55): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(15,53): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(16,55): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
Program.cs(1,7): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C:\temp\temp. csproj]
C:\Users\wangyi\AppData\Local\Temp\1\.NETCoreApp,Version=v2.2.AssemblyAttributes.cs(2,7): ошибка CS0246: не удалось найти тип или имя пространства имен "Система" (есть вы пропустили директиву using или ссылку на сборку?) [C:\temp\temp.csproj]
C:\Users\wangyi\AppData\Local\Temp\1\.NETCoreApp,Version=v2.2.AssemblyAttributes.cs(3,7): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (есть вы пропустили директиву using или ссылку на сборку?) [C:\temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(7,7): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
obj\Debug\netcoreapp2.2\temp.AssemblyInfo.cs(8,7): ошибка CS0246: не удалось найти тип или имя пространства имен 'System' (отсутствует директива using или ссылка на сборку?) [C: \ Temp\temp.csproj]
Program.cs(5,11): ошибка CS0518: предопределенный тип 'System.Object' не определен или не импортирован [C:\temp\temp. csproj]
Program.cs(7,26): ошибка CS0518: предопределенный тип 'System.String' не определен или не импортирован [C:\temp\temp.csproj]
Program.cs(7,16): ошибка CS0518: Предопределенный тип 'System.Void' не определен или не импортирован [C: \ temp \ temp.csproj]

Сборка не удалась. Пожалуйста, исправьте ошибки сборки и запустите снова.

Бег dotnet restore не получил никакой ошибки.

PS C:\temp> dotnet restore
Restore completed in 41.15 ms for C:\temp\temp.csproj.

Я попытался «удалить файлы C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder» ( https://github.com/dotnet/core/issues/1006), но это все равно не решило проблему.

Однако в Visual Studio проект компилируется и запускается после того, как я переключаю версию проекта.net core на 2.1.

Имена объектов в языке Си (C). Пространство имен

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

Чтобы различать идентификаторы объектов различного рода, компилятор языка Си устанавливает так называемые «пространства имен». Во избежание противоречий имена внутри одного пространства должны быть уникальными, однако в различных пространствах могут содержаться идентичные имена. Это означает, что можно использовать один и тот же идентификатор для двух или более различных объектов, если имена объектов принадлежат к различным пространствам. Однозначное разрешение вопроса о том, на какой объект ссылается идентификатор, компилятор языка Си осуществляет по контексту появления данного идентификатора в программе. Ниже перечисляются виды объектов, которые можно именовать в программе на языке Си, и соответствующие им четыре пространства имен.

Объекты

 

Пространство имен

Переменные, функции, формальные параметры, элементы списка перечисления, typedef

Уникальность имен в пределах этого пространства тесно связана с понятием области действия. Это выражается в том, что в данном пространстве могут содержаться совпадающие идентификаторы, если области действия именуемых ими объектов не пересекаются. Другими словами, совпадение идентификаторов возможно только при локальном переобъявлении (см. раздел 2.4). Обратите внимание на то, что имена формальных параметров функции сгруппированы в одном пространстве с именами локальных переменных. Поэтому переобъявление формальных параметров внутри любого из блоков функции недопустимо, typedef — это объявления имен типов (см. раздел 3.8.2).

Теги

Теги всех переменных перечислимого типа, структур и объединений (см. разделы 3.4.2-3.4.4.html3.4.4) сгруппированы в одном пространстве имен. Каждый тег переменной перечислимого типа, структуры или объединения должен быть отличен от других тегов с той же самой областью действия. Ни с какими другими именами имена тегов не конфликтуют.

Элементы структур и объединений

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

Метки операторов

Метки операторов образуют отдельное пространство имен. Каждая метка должна быть отлична от всех других меток операторов в той же самой функции. В разных функциях могут быть одинаковые метки.

Пример :

struct student
{
char student[20]; /* массив из 20 элементов типа char*/
int class;
int id;
} student; /*структура из трех элементов*/

В этом примере имя тега структуры, элемента структуры и самой структуры относится к трем различным пространствам имен, поэтому не возникает противоречия между тремя объектами с одинаковым именем student. Компилятор языка Си определит по контексту использования, на какой из объектов ссылается идентификатор в каждом конкретном случае. Например, когда идентификатор student появится после ключевого слова struct, это будет означать, что именуется тег структуры. Когда идентификатор student появится после операции выбора элемента (-> или . ), то это будет означать, что именуется элемент структуры. В любом другом контексте идентификатор student будет рассматриваться как ссылка на переменную структурного типа.

Решение: Имя типа или пространства имен «ComponentModel» отсутствует в пространстве имен «System»

Доброго времени суток!
Прошу прощения,если такая тема уже существует,но к сожалению ответа на свой вопрос так и не нашёл.
Собственно я нуб в програмировании на С# (только немного на С/С++).Задали сделать програмку,я,как настоящий студент,решил «позаимствовать» у других.Нашёл програмку на С#. Решил скомпилить,только что скачал Microsoft Visual Studio 10.0 (тот что экспресс) ,добавил 2 файла(моя прога состоит из 2-ух файлов .cs (один main.cs и Form1.cs ))нажал F5 и полетели ошибки…

Ошибка 1 Имя типа или пространства имен «ComponentModel» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 2 Имя типа или пространства имен «ComponentModel» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 3 Имя типа или пространства имен «Data» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 4 Имя типа или пространства имен «Data» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 5 Имя типа или пространства имен «Drawing» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 6 Имя типа или пространства имен «Drawing» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 7 Имя типа или пространства имен «Windows» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 8 Имя типа или пространства имен «Windows» отсутствует в пространстве имен «System» (пропущена ссылка на сборку?)
Ошибка 9 Не удалось найти имя типа или пространства имен «Form» (пропущена директива using или ссылка на сборку?)
Ошибка 10 Не удалось найти имя типа или пространства имен «DialogHelp» (пропущена директива using или ссылка на сборку?)

Собственно как решить данные проблемы?
Заранее спасибо.

Код к задаче: «Имя типа или пространства имен «ComponentModel» отсутствует в пространстве имен «System»»

Компилятор Не Найдет Пространство Имен ‘System.Windows.Interop’

Справка !! ** Компилятор не найдет пространство имен ** «System.Windows.Interop» ****

недавно я построил проект winform и хочу использовать dll (выполнить некоторую работу рендеринга d3d), сгенерированную другим c++ проектом;

OS: win7 x64
IDE: vs2013
Language:C#
current framework used in the winform project is ".net framework 4.5"

И в проекте winform я создал файл класса с именем MCDllOpt.cs. Код выглядит следующим образом.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Interop; // Error occured here!

namespace WorldEditor
{
class MCDllOpt
{

}
}

И вот часть того, что говорит компилятор.

1>CoreCompile:
1> C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu32bitpreferred /errorreport:prompt /warn:4 /define:TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Deployment.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\. NETFramework\v4.5.1\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Drawing.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Windows.Forms.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.Linq.dll" /debug:pdbonly /filealign:512 /optimize+ /out:obj\Release\WorldEditor.exe /subsystemversion:6.00 /resource:obj\Release\WorldEditor.Form1.resources /resource:obj\Release\WorldEditor.Properties.Resources.resources /target:winexe /utf8output Form1.cs Form1.Designer.cs MCDllOpt.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs "C:\Users\Think\AppData\Local\Temp\.NETFramework,Version=v4.5.1.AssemblyAttributes.cs" obj\Release\\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3. cs obj\Release\\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs obj\Release\\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
1>F:\WorldEditor\WorldEditor\WorldEditor\MCDllOpt.cs(6,22,6,29): error CS0234: The type or namespace name 'Interop' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.78
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

После нескольких минут поиска. Я узнал, что мне нужно добавить указанные ссылки. Но после того, как я добавлю все ссылки, префикс которых «System.Windows», проблема все еще не исправлена!

У кого-нибудь есть эта проблема раньше? Пожалуйста, помогите мне.

Компилятор won’ t находят пространство имен ‘ Система. Windows. Interop’

Помощь!! ** Компилятор не найдет пространство имен ** ‘Система. Windows. Interop’ ****

недавно я разработал проект winform, и хотят использовать dll (сделайте некоторую работу предоставления d3d), произведенный другим проектом C++;

OS: win7 x64
IDE: vs2013
Language:C#
current framework used in the winform project is ".net framework 4.5"

И в проекте winform, я создал файл класса под названием MCDllOpt.cs
Кодекс следующие.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Interop;//Error occured here!

namespace WorldEditor
{
    class MCDllOpt
    {

    }
}

И вот часть того, что говорит компилятор.

1>CoreCompile:
1>  C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu32bitpreferred /errorreport:prompt /warn:4 /define:TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\. NETFramework\v4.5.1\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Deployment.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Drawing.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Windows.Forms.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\. NETFramework\v4.5.1\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.Linq.dll" /debug:pdbonly /filealign:512 /optimize+ /out:obj\Release\WorldEditor.exe /subsystemversion:6.00 /resource:obj\Release\WorldEditor.Form1.resources /resource:obj\Release\WorldEditor.Properties.Resources.resources /target:winexe /utf8output Form1.cs Form1.Designer.cs MCDllOpt.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs "C:\Users\Think\AppData\Local\Temp\.NETFramework,Version=v4.5.1.AssemblyAttributes.cs" obj\Release\\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs obj\Release\\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs obj\Release\\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
1>F:\WorldEditor\WorldEditor\WorldEditor\MCDllOpt.cs(6,22,6,29): error CS0234: The type or namespace name 'Interop' does not exist in the namespace 'System. Windows' (are you missing an assembly reference?)
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.78
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

After several minutes’ searching.I found out that I need to add references specified.
But after I add all the references whose prefix is ‘System.Windows’,the problem’s still not fixed!

У кого-либо есть эта проблема прежде?Please help me.

Использование пространства имен | Программирование на C и C++

Поскольку пространства с глобальной областью видимости добавляются к системе, то имеется возможность возникновения коллизии имен. Это становится особенно актуальным при использо­вании библиотек, разработанных различными независимыми производителями. Использование
namespace позволяет разбить глобальное пространство имен с тем, чтобы решить подобную про­блему. По существу, namespace определяет область видимости. Общая форма namespace представлена ниже:

namespace имя {
// объявление объекта
}

Кроме того, можно использовать безымянное пространство имен, как показано ниже:

namespace {
// объявление объекта
}

Безымянное пространство имен позволяет определить уникальность идентификаторов с областью видимости в пределах единственного файла.

Ниже приведен пример использования namespace:

namespace MyNameSpace {
int i, k;
void myfunc(int j) { cout << j; }
}

Здесь i, k и myfunc() составляют область видимости пространства имен MyNameSpace.

Поскольку пространство имен определяет область видимости, то для ссылки на объекты, опре­деленные в пространстве имен, необходимо использовать оператор области видимости. Напри­мер, чтобы присвоить значение 10 переменной i, необходимо использовать следующую инструк­цию:

MyNameSpace::i =10;

Если элементы области пространства имен будут использоваться часто, то можно использовать директиву using для упрощения доступа к ним. Инструкция using имеет две общие формы записи:

using namespace имя;

using имя::член;

В первом варианте имя определяет имя пространства имен, к которому нужно получить доступ. Все члены, определенные в указанном пространстве имен, могут быть использованы без использо­вания оператора области видимости. Во втором варианте только указанные члены пространства имен становятся видимыми. Например, для определенного выше пространства имен MyNameSpace следующее использование инструкции using является корректным:

using MyNameSpace::k; // видим только k
k = 10; // допустимо, поскольку k видим
using namespace MyNameSpace; // все члены MyNameSpace видимы
i = 10; // допустимо, поскольку все члены MyNameSpace видимы

c ++ — «Система» не является именем пространства имен

Я использую некоторые пространства имен .Net в моем коде на C ++. Отсюда я понял, как я могу это сделать. В моем коде:

  #include 
using пространство имен System;
используя пространство имен System :: Data;
с использованием пространства имен System :: Data :: Sql;
используя пространство имен Microsoft :: Sqlserver :: Server;
с использованием пространства имен System :: Data :: SqlTypes;

используя пространство имен std;

int main ()
{


    cout << "Hello World!" << endl;
    возврат 0;
}
  

Если я запустил его, я получаю следующие ошибки:

  0:08:06: Выполнение шагов для проекта Test. ..
10:08:06: Конфигурация не изменилась, шаг qmake пропущен.
10:08:06: Запуск: "/ usr / bin / make"
g ++ -c -m64 -pipe -g -Wall -W -DQT_WEBKIT -I / usr / share / qt4 / mkspecs / linux-g ++ - 64 -I ../ Test -I ../ Test -I. -o main.o ../Test/main.cpp
../Test/main.cpp:2:17: error: "Система" не является именем-пространством имен
../Test/main.cpp:2:23: error: ожидаемое имя-пространства имен перед ';' жетон
../Test/main.cpp:3:17: error: «Система» не объявлена
../Test/main.cpp:3:25: error: «Данные» не являются именем пространства имен
../Test/main.cpp:3:29: error: ожидаемое имя-пространства имен перед ';' жетон
../Test/main.cpp:4:17: error: 'Система' не была объявлена
../Test/main.cpp:4:31: ошибка: 'Sql' не является именем-пространством имен
../Test/main.cpp:4:34: error: ожидаемое имя-пространства имен перед ';' жетон
../Test/main.cpp:5:17: ошибка: «Microsoft» не объявлено
../Test/main.cpp:5:39: ошибка: «Сервер» не является именем-пространством имен
../Test/main.cpp:5:45: error: ожидаемое имя-пространства имен перед ';' жетон
. ./Test/main.cpp:6:17: error: 'Система' не была объявлена
../Test/main.cpp:6:31: ошибка: 'SqlTypes' не является именем пространства имен
../Test/main.cpp:6:39: error: ожидаемое имя-пространства имен перед ';' жетон
make: *** [main.o] Ошибка 1
10:08:06: Процесс "/ usr / bin / make" завершился с кодом 2.
Ошибка при создании / развертывании проекта Test (комплект: рабочий стол)
При выполнении шага Make
10:08:06: Прошедшее время: 00:00.
  

что мне делать, чтобы решить эту проблему?
Кстати, я читал этот и этот посты, но не мог понять, что мне делать с / clr в моем коде cpp?

пространств имен (7) - страница руководства Linux

пространства имен (7) - страница руководства Linux


NAMESPACES (7) Руководство программиста Linux NAMESPACES (7)
 

НАЗВАНИЕ сверху

       namespaces - обзор пространств имен Linux
 

ОПИСАНИЕ вверху

       Пространство имен обертывает глобальный системный ресурс в абстракцию, которая
       заставляет процессы в пространстве имен казаться, что они
       имеют собственный изолированный экземпляр глобального ресурса. Изменения
       к глобальному ресурсу видны другим процессам, которые
       члены пространства имен, но невидимы для других процессов.
       Одно из применений пространств имен - реализация контейнеров.

       Эта страница содержит указатели на информацию о различных
       типы пространств имен, описывает связанные файлы  / proc  и
       резюмирует API для работы с пространствами имен.

     Типы пространств имен 
       В следующей таблице показаны типы пространств имен, доступные в Linux.Второй столбец таблицы показывает используемое значение флага.
       для указания типа пространства имен в различных API. Третий столбец
       идентифицирует страницу руководства, которая предоставляет подробную информацию о пространстве имен
       тип. Последний столбец представляет собой сводку ресурсов, которые
       изолированные по типу пространства имен.

         Страница флага пространства имен изолирует 
       Cgroup  CLONE_NEWCGROUP cgroup_namespaces  (7) Корень Cgroup
                                                       каталог
       IPC  CLONE_NEWIPC ipc_namespaces  (7) System V IPC, POSIX
                                                       очереди сообщений
       Сеть  CLONE_NEWNET network_namespaces  (7) Сетевые устройства,
                                                       стеки, порты и т.  д.Mount  CLONE_NEWNS mount_namespaces  (7) Точки монтирования
       PID  CLONE_NEWPID pid_namespaces  (7) Идентификаторы процесса
       Время  CLONE_NEWTIME time_namespaces  (7) Загрузочная и монотонная
                                                       часы
       Пользователь  CLONE_NEWUSER user_namespaces  (7) T {Идентификаторы пользователя и группы
       T}
       UTS  CLONE_NEWUTS uts_namespaces  (7) Имя хоста и NIS
                                                       доменное имя

     Пространства имен API 
       Помимо различных файлов  / proc , описанных ниже, пространства имен
       API включает следующие системные вызовы:

       клон (2)
              Системный вызов clone (2) создает новый процесс.Если
                flags  аргумент вызова указывает один или несколько из
                CLONE_NEW *  флаги перечислены ниже, затем новые пространства имен
              создается для каждого флага, а дочерний процесс превращается в
              член этих пространств имен.  (Этот системный вызов также
              реализует ряд функций, не связанных с пространствами имен.)

       сетнс (2)
              Системный вызов setns (2) позволяет вызывающему процессу
              присоединиться к существующему пространству имен.Пространство имен для присоединения:
              указывается через дескриптор файла, который относится к одному из
                / proc / [pid] / ns  файлов, описанных ниже.

       не делиться (2)
              Системный вызов unshare (2) перемещает вызывающий процесс в
              новое пространство имен. Если  отмечает  аргумент вызова
              указывает один или несколько из перечисленных флагов  CLONE_NEW * 
              ниже для каждого флага создаются новые пространства имен, и
              вызывающий процесс становится членом этих пространств имен.(Этот системный вызов также реализует ряд функций
              не имеет отношения к пространствам имен.)

       ioctl (2)
              Различные операции ioctl (2) могут использоваться для обнаружения
              информация о пространствах имен.  Эти операции
              описан в ioctl_ns (2).

       Создание новых пространств имен с использованием clone (2) и unshare (2) в большинстве
       случаях требуется возможность  CAP_SYS_ADMIN , поскольку в новом
       пространство имен, создатель будет иметь право изменять глобальные
       ресурсы, которые видны другим процессам, которые
       впоследствии создается в пространстве имен или присоединяется к нему.Пользовательские пространства имён
       являются исключением: начиная с Linux 3.8, для
       создать пространство имен пользователя.

     Каталог / proc / [pid] / ns / 
       У каждого процесса есть подкаталог  / proc / [pid] / ns / , содержащий один
       запись для каждого пространства имен, которое поддерживает манипулирование
       setns (2):

           $  ls -l / proc / $$ / ns | awk '{print $ 1, 9, 10, 11 долларов}' 
           всего 0
           lrwxrwxrwx. cgroup -> cgroup: [4026531835]
           lrwxrwxrwx.ipc -> ipc: [4026531839]
           lrwxrwxrwx.  mnt -> mnt: [4026531840]
           lrwxrwxrwx. сеть -> сеть: [4026531969]
           lrwxrwxrwx. pid -> pid: [4026531836]
           lrwxrwxrwx. pid_for_children -> pid: [4026531834]
           lrwxrwxrwx. время -> время: [4026531834]
           lrwxrwxrwx. time_for_children -> время: [4026531834]
           lrwxrwxrwx. пользователь -> пользователь: [4026531837]
           lrwxrwxrwx. uts -> uts: [4026531838]

       Привязать монтирование (см. Mount (2)) к одному из файлов в этом каталоге
       в другое место в файловой системе хранит соответствующий
       пространство имен процесса, указанного в  pid , живое, даже если все
       процессы, находящиеся в данный момент в пространстве имен, завершаются.Открытие одного из файлов в этом каталоге (или файла,
       bind, подключенный к одному из этих файлов) возвращает дескриптор файла для
       соответствующее пространство имен процесса, указанного в  pid . Пока
       поскольку этот файловый дескриптор остается открытым, пространство имен останется
       живы, даже если все процессы в пространстве имен завершаются.  В
       дескриптор файла может быть передан в setns (2).

       В Linux 3.7 и ранее эти файлы были видны как жесткие ссылки.
       Начиная с Linux 3.8 они отображаются как символические ссылки. Если два процесса
       находятся в одном пространстве имен, то идентификаторы устройств и номера inode
       из их  / proc / [pid] / ns / xxx  символьных ссылок будут такими же; ан
       приложение может проверить это с помощью  stat.st_dev  и  stat.st_ino 
       поля, возвращаемые stat (2). Содержание этой символической ссылки
       строка, содержащая тип пространства имен и номер inode, как в
       следующий пример:

           $  readlink / proc / $$ / ns / uts 
           uts: [4026531838]

       Символьные ссылки в этом подкаталоге следующие:

         / proc / [pid] / ns / cgroup  (начиная с Linux 4.6)
              Этот файл является дескриптором пространства имен cgroup
              процесс.

         / proc / [pid] / ns / ipc  (начиная с Linux 3. 0)
              Этот файл является дескриптором пространства имен IPC
              процесс.

         / proc / [pid] / ns / mnt  (начиная с Linux 3.8)
              Этот файл является дескриптором пространства имен монтирования
              процесс.

         / proc / [pid] / ns / net  (начиная с Linux 3.0)
              Этот файл представляет собой дескриптор сетевого пространства имен
              процесс. / proc / [pid] / ns / pid  (начиная с Linux 3.8)
              Этот файл является дескриптором пространства имен PID
              процесс. Эта ручка остается постоянной в течение всего срока службы
              процесс (т.е. членство в пространстве имен PID процесса никогда не
              изменения).

         / proc / [pid] / ns / pid_for_children  (начиная с Linux 4.12)
              Этот файл является дескриптором пространства имен PID дочернего элемента.
              процессы, созданные этим процессом. Это может измениться как
              следствие вызовов unshare (2) и setns (2) (см. 
              pid_namespaces (7)), поэтому файл может отличаться от
                / proc / [pid] / ns / pid .Символьная ссылка получает только значение
              после создания первого дочернего процесса в пространстве имен.
              (Предварительно readlink (2) символической ссылки вернет
              пустой буфер.)

         / proc / [pid] / ns / time  (начиная с Linux 5.6)
              Этот файл является дескриптором пространства имен времени
              процесс.

         / proc / [pid] / ns / time_for_children  (начиная с Linux 5.6)
              Этот файл является дескриптором пространства имен дочернего элемента
              процессы, созданные этим процессом.Это может измениться как
              следствие вызовов unshare (2) и setns (2) (см.
              time_namespaces (7)), поэтому файл может отличаться от
                / proc / [pid] / нс / время .

         / proc / [pid] / ns / user  (начиная с Linux 3.8)
              Этот файл представляет собой дескриптор пользовательского пространства имен
              процесс. 

         / proc / [pid] / ns / uts  (начиная с Linux 3.0)
              Этот файл является описателем пространства имен UTS
              процесс.

       Разрешение на разыменование или чтение (ссылка для чтения (2)) этих символических
       ссылки регулируются режимом доступа ptrace
         PTRACE_MODE_READ_FSCREDS  проверка; см. ptrace (2). Каталог / proc / sys / user 
       Файлы в каталоге  / proc / sys / user  (который присутствует с
       Linux 4.9) выставляют ограничения на количество пространств имен различных
       типы, которые могут быть созданы. Это следующие файлы:

         max_cgroup_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен cgroup, которые могут быть созданы в
              пространство имен пользователя.

         max_ipc_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен ipc, которые могут быть созданы пользователем
              пространство имен.  max_mnt_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен монтирования, которые могут быть созданы пользователем
              пространство имен.

         max_net_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество сетевых пространств имен, которые могут быть созданы в
              пространство имен пользователя.

         max_pid_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен PID, которые могут быть созданы в пользователе
              пространство имен. max_time_namespaces  (начиная с Linux 5.7)
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен времени, которые могут быть созданы в пользователе
              пространство имен.

         max_user_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пользовательских пространств имен, которые могут быть созданы в пользователе
              пространство имен. 

         max_uts_namespaces 
              Значение в этом файле определяет ограничение для каждого пользователя
              количество пространств имен uts, которые могут быть созданы пользователем
              пространство имен.Обратите внимание на следующие сведения об этих файлах:

       * Значения в этих файлах могут быть изменены привилегированными
          процессы.

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

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

       * Ограничения распространяются на всех пользователей, включая UID 0.

       * Эти ограничения применяются в дополнение к любому другому пространству имен
          ограничения (например, для PID и пользовательских пространств имен), которые могут быть
          принудительно. * При достижении этих ограничений clone (2) и unshare (2) терпят неудачу
          с ошибкой  ENOSPC .

       * Для исходного пространства имен пользователя значение по умолчанию в каждом из
          эти файлы составляют половину ограничения на количество потоков, которые
          могут быть созданы ( / proc / sys / kernel / threads-max ). В целом
          потомков пользовательских пространств имен, значение по умолчанию в каждом файле
            МАКСИНТ .

       * При создании пространства имен объект также учитывается
          против пространств имен предков.Точнее:

          + У каждого пользовательского пространства имен есть UID создателя.

          + Когда пространство имен создается, оно учитывается
             UID создателя в каждом из пользовательских пространств имен-предков, и
             ядро гарантирует, что соответствующий предел пространства имен
             для UID создателя в пространстве имен предка не
             превышено.

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

       * Дескриптор открытого файла или привязка существует для
          соответствующий файл  / proc / [pid] / ns / * .* Пространство имен является иерархическим (например, PID или пользовательское пространство имен),
          и имеет дочернее пространство имен.

       * Это пространство имен пользователя, которому принадлежит один или несколько пользователей, не являющихся пользователями.
          пространства имен.

       * Это пространство имен PID, и есть процесс, который относится к
          пространство имен через символический  / proc / [pid] / ns / pid_for_children 
          ссылка на сайт. 

       * Это пространство имен времени, и есть процесс, который относится к
          пространство имен через символический  / proc / [pid] / ns / time_for_children 
          ссылка на сайт.* Это пространство имен IPC и соответствующее крепление  mqueue 
          файловая система (см. mq_overview (7)) относится к этому пространству имен.

       * Это пространство имен PID и соответствующее монтирование proc (5)
          файловая система относится к этому пространству имен.
 

ПРИМЕРЫ наверху

       Смотрите clone (2) и user_namespaces (7).
 

СМОТРИТЕ ТАКЖЕ top

       nsenter (1), ссылка для чтения (1), unshare (1), clone (2), ioctl_ns (2),
       setns (2), unshare (2), proc (5), возможности (7),
       cgroup_namespaces (7), cgroups (7), учетные данные (7),
       ipc_namespaces (7), network_namespaces (7), pid_namespaces (7),
       user_namespaces (7), uts_namespaces (7), lsns (8), pam_namespace (8),
       switch_root (8)
 

COLOPHON верх

       Эта страница является частью версии 5. 11 из проекта  справочных страниц Linux .
       Описание проекта, информация о сообщениях об ошибках,
       и последнюю версию этой страницы можно найти по адресу
       https://www.kernel.org/doc/man-pages/.


 

Страницы, которые относятся к этой странице:
nsenter (1),
procps (1),
пс (1),
systemd-обнаружение-вирт (1),
не делиться (1),
клон (2),
getdomainname (2),
gethostname (2),
ioctl_ns (2),
сетнс (2),
не делить (2),
proc (5),
systemd.exec (5),
cgroup_namespaces (7),
cgroups (7),
учетные данные (7),
ipc_namespaces (7),
mount_namespaces (7),
mq_overview (7),
network_namespaces (7),
pid_namespaces (7),
time_namespaces (7),
user_namespaces (7),
uts_namespaces (7),
lsns (8),
rdma-система (8)


Авторские права и лицензия на это руководство, страница

Создание контейнера вручную с использованием пространств имен: пространство имен mount

Эта статья рассматривает пространство имен mount и является третьей в серии пространств имен Linux. В первой статье я представил семь наиболее часто используемых пространств имен, заложив основу для практической работы, начатой ​​в статье о пользовательских пространствах имен. Моя цель - получить некоторые фундаментальные знания о том, как работают контейнеры Linux. Если вас интересует, как Linux управляет ресурсами в системе, ознакомьтесь с серией статей о CGroup, о которых я писал ранее. Надеюсь, к тому времени, когда вы закончите практическую работу с пространствами имен, я смогу связать CGroups и пространства имен вместе значимым образом, завершив для вас картину.

На данный момент, однако, в этой статье исследуется пространство имен mount и то, как оно может помочь вам приблизиться к пониманию изоляции, которую контейнеры Linux привносят системным администраторам и, соответственно, платформам, таким как OpenShift и Kubernetes.

[Вам также может понравиться: Совместное использование дополнительных групп с контейнерами Podman]

Пространство имен mount

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

Некоторые шаги настройки для монтирования пространств имен

Так в чем же тогда смысл пространства имен mount? Чтобы продемонстрировать это, я использую tar-архив Alpine Linux.

Таким образом, загрузите его, распакуйте и переместите в новый каталог, предоставив права доступа к каталогу верхнего уровня для непривилегированного пользователя:

  [root @ localhost ~] экспорт CONTAINER_ROOT_FOLDER = / container_practice
[root @ localhost ~] mkdir -p $ {CONTAINER_ROOT_FOLDER} / fakeroot
[root @ localhost ~] cd $ {CONTAINER_ROOT_FOLDER}
[root @ localhost ~] wget https://dl-cdn. alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.1-x86_64.tar.gz
[корень @ localhost ~] tar xvf alpine-minirootfs-3.13.1-x86_64.tar.gz -C fakeroot
[root @ localhost ~] chown пользователь-контейнер. -R $ {CONTAINER_ROOT_FOLDER} / fakeroot  

Каталог fakeroot должен принадлежать пользователю контейнера-пользователя , потому что после создания нового пространства имен пользователь root пользователь в новом пространстве имен будет сопоставлен с пользователем-контейнером вне пространства имен . Это означает, что процесс внутри нового пространства имен будет думать, что у него есть возможности, необходимые для изменения своих файлов.Тем не менее, разрешения файловой системы хоста не позволят учетной записи пользователя-контейнера изменять файлы Alpine из архива (владельцем которых является корень ).

Итак, что произойдет, если вы просто запустите новое пространство имен монтирования?

  PS1 = '\ u @ new-mnt $' unshare -Umr  

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

  корень @ new-mnt $ df -h
Используемый размер файловой системы Доступность% Установлено на
/ dev / mapper / cs-root 36 ГБ 5.2G 31G 15% /
tmpfs 737M 0 737M 0% / sys / fs / cgroup
devtmpfs 720M 0 720M 0% / dev
tmpfs 737M 0 737M 0% / dev / shm
tmpfs 737M 8,6M 728M 2% / запуск
tmpfs 148M 0 148M 0% / run / user / 0
/ dev / vda1 976M 197M 713M 22% / boot


корень @ new-mnt $ ls /
bin container_practice и т. д. lib media opt root sbin sys usr
boot dev home lib64 mnt proc run srv tmp var  

Причина этого в том, что systemd по умолчанию рекурсивно разделяет точки монтирования со всеми новыми пространствами имен.Если вы смонтировали файловую систему tmpfs где-нибудь, например, / mnt внутри нового пространства имен монтирования, сможет ли хост ее увидеть?

  корень @ новый-mnt $ mount -t tmpfs tmpfs / mnt

корень @ new-mnt $ findmnt | grep mnt
└─ / mnt tmpfs tmpfs rw, relatime, seclabel, uid = 1000, gid = 1000  

Хост, однако, этого не видит:

  [корень @ localhost ~] # findmnt | grep mnt  

Итак, по крайней мере, вы знаете, что пространство имен mount работает правильно. Это хорошее время, чтобы сделать небольшой крюк, чтобы обсудить распространение точек монтирования. Я кратко резюмирую, но если вас интересует более глубокое понимание, взгляните на статью Майкла Керриска LWN, а также на страницу руководства для пространства имен mount. Обычно я не так сильно полагаюсь на страницы руководства, так как часто обнаруживаю, что они нелегко усваиваются. Однако в данном случае они полны примеров и на (в основном) простом английском языке.

Теория точек крепления

Монтирования распространяются по умолчанию из-за функции ядра, называемой общим поддеревом .Это позволяет каждой точке монтирования иметь связанный с ней собственный тип распространения. Эти метаданные определяют, будут ли новые точки монтирования по заданному пути распространяться на другие точки монтирования. На странице руководства приведен пример оптического диска. Если ваш оптический диск автоматически смонтирован под / cdrom , его содержимое будет видно в других пространствах имен, только если установлен соответствующий тип распространения.

Одноранговые группы и состояния монтирования

В документации к ядру сказано, что « одноранговая группа определяется как группа vfsmounts, которые передают события друг другу.«События - это такие вещи, как подключение общего сетевого ресурса или размонтирование оптического устройства. Почему это важно, спросите вы? Что ж, когда дело доходит до пространства имен монтирования, группы равноправных узлов , часто являются решающим фактором относительно того, нужно ли монтировать виден и с ним можно взаимодействовать. Состояние монтирования определяет, может ли член в одноранговой группе получить событие. Согласно той же документации ядра, существует пять состояний монтирования:

  1. общий - монтирование, которое принадлежит одноранговой группе.Любые происходящие изменения будут распространяться на всех членов одноранговой группы.
  2. slave - Одностороннее распространение. Главная точка монтирования будет распространять события на ведомое устройство, но ведущее устройство не будет видеть никаких действий, предпринимаемых ведомым устройством.
  3. общий и подчиненный - указывает, что точка монтирования имеет главный сервер, но также имеет свою собственную группу одноранговых узлов. Мастер не будет уведомлен об изменениях точки монтирования, но все члены группы одноранговых узлов, расположенные ниже по потоку, будут.
  4. частный - не получает и не пересылает никаких событий распространения.
  5. unbindable - Не получает и не пересылает никаких событий распространения, а не может быть подключен к .

Важно отметить, что состояние точки монтирования - для каждой точки монтирования . Это означает, что, например, если у вас / и / boot , вам придется отдельно применить желаемое состояние к каждой точке монтирования.

Если вас интересуют контейнеры, большинство движков контейнеров используют частные состояния монтирования при монтировании тома внутри контейнера. Не беспокойтесь об этом сейчас. Я просто хочу предоставить некоторый контекст. Если вы хотите попробовать какие-то конкретные сценарии монтирования, посмотрите справочные страницы, так как примеры довольно хороши.

Создание пространства имен монтирования

Если вы используете такой язык программирования, как Go или C, вы можете использовать необработанные системные вызовы ядра для создания соответствующей среды для вашего нового пространства (пространств) имен. Однако, поскольку цель этого состоит в том, чтобы помочь вам понять, как взаимодействовать с уже существующим контейнером, вам придется проделать некоторые уловки с bash, чтобы привести новое пространство имен монтирования в желаемое состояние.

Сначала создайте новое пространство имен монтирования как обычный пользователь:

  не делиться -Urm  

Как только вы окажетесь внутри пространства имен, посмотрите на findmnt устройства отображения, которое содержит корневую файловую систему (для краткости я удалил большинство параметров монтирования из вывода):

  findmnt | программа для отображения grep

/ / Dev / mapper / cs-root xfs rw, relatime, [. ..]  

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

  экспорт CONTAINER_ROOT_FOLDER = / container_practice
mount --bind $ {CONTAINER_ROOT_FOLDER} / fakeroot $ {CONTAINER_ROOT_FOLDER} / fakeroot
cd $ {CONTAINER_ROOT_FOLDER} / fakeroot  

Это связано с тем, что вы используете утилиту pivot_root для выполнения действия, аналогичного chroot . pivot_root принимает два аргумента: new_root и old_root (иногда называемый put_old ). pivot_root перемещает корневую файловую систему текущего процесса в каталог put_old и делает new_root новой корневой файловой системой.

ВАЖНО : Примечание о chroot . chroot часто рассматривается как средство обеспечения дополнительной безопасности. В некоторой степени это правда, поскольку для того, чтобы освободиться от этого, требуется более значительный опыт. Тщательно сконструированный chroot может быть очень безопасным. Однако chroot не изменяет и не ограничивает возможности Linux, о которых я говорил в предыдущей статье о пространстве имен.Он также не ограничивает системные вызовы ядра. Это означает, что достаточно опытный злоумышленник потенциально может избежать непродуманного chroot . Пространства имен mount и user помогают решить эту проблему.

Если вы используете pivot_root без привязки, команда отвечает:

  pivot_root: не удалось изменить корневой каталог с `. ' to `old_root / ': недопустимый аргумент  

Чтобы переключиться на корневую файловую систему Alpine, сначала создайте каталог для old_root , а затем перейдите в предполагаемую корневую файловую систему (Alpine).Поскольку в корневой файловой системе Alpine Linux нет символических ссылок для / bin и / sbin , вам придется добавить их в свой путь, а затем, наконец, размонтировать old_root :

  мкдир old_root
pivot_root.  old_root
ПУТЬ = / bin: / sbin: $ ПУТЬ
umount -l / старый_root  

Теперь у вас есть хорошая среда, в которой пользовательские и монтируют пространства имен работают вместе, чтобы обеспечить уровень изоляции от хоста. У вас больше нет доступа к двоичным файлам на хосте.Попробуйте ввести команду findmnt , которую вы использовали раньше:

  корень @ new-mnt $ findmnt
-bash: findmnt: команда не найдена  

Вы также можете посмотреть корневую файловую систему или попытаться увидеть, что смонтировано:

  корень @ new-mnt $ ls -l /
всего 12
drwxr-xr-x 2 root root 4096 28 января 21:51 bin
drwxr-xr-x 2 root root 18 17 фев 22:53 dev
drwxr-xr-x 15 root root 4096 28 января 21:51 и т. д.
drwxr-xr-x 2 root root 6 28 янв 21:51 домой
drwxr-xr-x 7 root root 247 28 января 21:51 lib
drwxr-xr-x 5 root root 44 28 января 21:51 медиа
drwxr-xr-x 2 root root 6 28 янв 21:51 мин.
drwxrwxr-x 2 root root 6 фев 17 23:09 old_root
drwxr-xr-x 2 root root 6 28 января 21:51 opt
drwxr-xr-x 2 root root 6 28 янв 21:51 proc
drwxr-xr-x 2 root root 6 17 фев 22:53 put_old
drwx ------ 2 корень корень 27 фев 17 22:53 корень
drwxr-xr-x 2 root root 6 28 янв 21:51 запустить
drwxr-xr-x 2 root root 4096 28 янв 21:51 sbin
drwxr-xr-x 2 root root 6 28 янв 21:51 srv
drwxr-xr-x 2 root root 6 28 января 21:51 sys
drwxrwxrwt 2 root root 6 фев 19 16:38 tmp
drwxr-xr-x 7 root root 66 28 янв 21:51 usr
drwxr-xr-x 12 root root 137 28 января 21:51 var


корень @ new-mnt $ mount
mount: no / proc / mounts  

Интересно, что по умолчанию файловая система proc не смонтирована. Попробуйте смонтировать:

  корень @ новый-mnt $ mount -t proc proc / proc
mount: в разрешении отказано (вы root?)

корень @ new-mnt $ whoami
корень  

Поскольку proc - это особый тип монтирования, связанный с пространством имен PID, вы не можете его смонтировать, даже если вы находитесь в своем собственном пространстве имен монтирования. Это восходит к наследованию возможностей, которое я обсуждал ранее. Я продолжу это обсуждение в следующей статье, когда расскажу о пространстве имен PID. Однако, как напоминание о наследовании, взгляните на диаграмму ниже:

В следующей статье я перепишу эту диаграмму, но если вы следовали ей с самого начала, вы сможете сделать некоторые выводы до этого.

[Руководство пользователя API: 7 лучших практик эффективных программ API]

Завершение

В этой статье я рассмотрел более глубокую теорию пространства имен mount. Я обсудил группы одноранговых узлов и их отношение к состояниям монтирования, которые применяются к каждой точке монтирования в системе. Для практической части вы загрузили минимальную файловую систему Alpine Linux, а затем рассмотрели, как использовать пространства имен пользователя и монтировать для создания среды, которая очень похожа на chroot , за исключением потенциально более безопасной.

А пока протестируйте монтирование файловых систем внутри и вне вашего нового пространства имен. Попробуйте создать новые точки монтирования, которые используют общие состояния монтирования , , , частный, и подчиненный, . В следующей статье я буду использовать пространство имен PID, чтобы продолжить построение примитивного контейнера, чтобы получить доступ к файловой системе proc и изоляции процессов.

Пространства имен

и область действия в Python - Real Python

Встроенное пространство имен содержит имена всех встроенных объектов Python.Они доступны всегда, когда Python запущен. Вы можете перечислить объекты во встроенном пространстве имен с помощью следующей команды:

>>>

  >>> dir (__ builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError',
 BaseException, BlockingIOError, BrokenPipeError, BufferError,
 BytesWarning, ChildProcessError, ConnectionAbortedError,
 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError',
 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
 'Исключение', 'Ложь', 'FileExistsError', 'FileNotFoundError',
 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError',
 ImportError, ImportWarning, IndentationError, IndexError,
 InterruptedError, IsADirectoryError, KeyError, KeyboardInterrupt,
 LookupError, MemoryError, ModuleNotFoundError, NameError, None,
 NotADirectoryError, NotImplemented, NotImplementedError, OSError,
 'OverflowError', 'PendingDeprecationWarning', 'PermissionError',
 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning',
 RuntimeError, RuntimeWarning, StopAsyncIteration, StopIteration,
 SyntaxError, SyntaxWarning, SystemError, SystemExit, TabError,
 TimeoutError, True, TypeError, UnboundLocalError,
 UnicodeDecodeError, UnicodeEncodeError, UnicodeError,
 UnicodeTranslateError, UnicodeWarning, UserWarning, ValueError,
 'Предупреждение', 'ZeroDivisionError', '_', '__build_class__', '__debug__',
 '__doc__', '__import__', '__loader__', '__name__', '__package__',
 '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray',
 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'сложный',
 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate',
 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset',
 getattr, globals, hasattr, hash, help, hex, id, input,
 'int', 'isinstance', 'issubclass', 'iter', 'len', 'лицензия', 'список',
 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'объект', 'oct',
 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr',
 'reverse', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'обратный', 'круглый', 'набор', 'setattr', 'slice', 'sorted', 'staticmethod',
 str, sum, super, tuple, type, vars, zip]
  

Здесь вы увидите некоторые объекты, которые вы можете узнать из предыдущих руководств, например, исключение StopIteration , встроенные функции, такие как max () и len () , и типы объектов, такие как int и ул. .

Интерпретатор Python при запуске создает встроенное пространство имен. Это пространство имен остается существующим до завершения работы интерпретатора.

Пространства имен XML


Пространства имен XML предоставляют метод, позволяющий избежать конфликтов имен элементов.


Конфликты имен

В XML имена элементов определяются разработчиком. Это часто приводит к конфликту при попытке смешать XML-документы из разных XML-приложений.

Этот XML-код содержит информацию таблицы HTML:

<таблица>

Яблоки Бананы

Этот XML-код содержит информацию о столе (предмете мебели):

<таблица>

Африканский журнальный столик

80

120

Если бы эти фрагменты XML были сложены вместе, возник бы конфликт имен. Оба содержат элемент

, но имеют разное содержание и значение.

Пользователь или приложение XML не будут знать, как обрабатывать эти различия.


Разрешение конфликта имен с помощью префикса

Конфликтов имен в XML можно легко избежать с помощью префикса имени.

Этот XML-код содержит информацию о таблице HTML и предмете мебели:

Яблоки

Бананы


Африканский журнальный столик
80
120

В приведенном выше примере конфликта не будет, потому что два элемента

имеют разные имена.



Пространства имен XML - Атрибут xmlns

При использовании префиксов в XML необходимо определить пространство имен для префикса.

Пространство имен может быть определено атрибутом xmlns в начальном теге элемента.

Объявление пространства имен имеет следующий синтаксис. xmlns: префикс = " URI ".



Яблоки
Бананы


Африканский журнальный столик
80
120

В приведенном выше примере:

Атрибут xmlns в первом элементе

дает префиксу h: полное пространство имен.

Атрибут xmlns во втором элементе

дает префиксу f: полное пространство имен.

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

Пространства имен также могут быть объявлены в корневом элементе XML:

xmlns: f = "https://www. w3schools.com/furniture">



Яблоки
Бананы


Африканский журнальный столик
80
120

Примечание: URI пространства имен не используется анализатором для поиска информации.

Цель использования URI - дать пространству имен уникальное имя.

Однако компании часто используют пространство имен как указатель на
веб-страница, содержащая информацию о пространстве имен.


Универсальный идентификатор ресурса (URI)

Универсальный идентификатор ресурса (URI) - это строка символов, которая идентифицирует Интернет-ресурс.

Наиболее распространенным URI является универсальный указатель ресурсов (URL), который идентифицирует адрес домена в Интернете.Другой, не столь распространенный тип URI - это Uniform Resource Name (URN).


Пространства имен по умолчанию

Определение пространства имен по умолчанию для элемента избавляет нас от использования префиксов во всех дочерних элементах. Он имеет следующий синтаксис:

Этот XML-код содержит информацию таблицы HTML:

Яблоки Бананы

Этот XML-код содержит информацию о предмете мебели:

Африканский журнальный столик

80

120


Пространства имен в реальном использовании

XSLT - это язык, который можно использовать для преобразования XML-документов в другие форматы.

XML-документ ниже - это документ, используемый для преобразования XML в HTML.

Пространство имен http://www.w3.org/1999/XSL/Transform определяет XSLT
элементы внутри HTML-документа:

"?>

0 "
xmlns: xsl = "http://www.w3.org/1999/XSL/Transform">



Моя коллекция компакт-дисков


Заголовок Художник



Если вы хотите узнать больше о XSLT, прочтите наш
Учебное пособие по XSLT.

Использование пространств имен в вычислениях: определение и примеры - бизнес-класс [2021]

Примеры

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

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

К / С ++

Пространство имен помогает обеспечить правильное использование setPrice (). Теперь давайте посмотрим, как Java обрабатывает пространства имен.

Пакет Java

В Java пакет на самом деле является пространством имен. Это та же концепция, что и в C ++ (и для всех приложений пространств имен). Вы группируете связанные элементы вместе и обеспечиваете правильную ссылку на нужный объект. В этом примере показано одно приложение Java с несколькими пакетами для приложения Coffee.

В приведенном выше коде основная программа «Кофе» состоит из двух пакетов: кофе и продавца. В каждом из них есть класс Coffee, который может иметь много одинаковых имен для переменных и функций. Использование пакета (пространства имен) позволяет упорядочить эти объекты.

Другие языки программирования, поддерживающие пространства имен, включают Visual Basic и C #. Пространства имен также используются при настройке файловой системы или сети.

XML

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

Файловая система

В операционных системах Unix и Windows расположение файлов определяется путем:

  • C: \ Users \ mdg13 \ Documents \ - указывает Windows, где сохранить локальные документы для пользователя mdg13. У других пользователей в сети будет своя собственная папка.
  • / usr / local / apache - указывает серверам Unix, где следует сохранять файлы Apache.

В любой файловой системе имена файлов в каждой папке уникальны. Фактически, вы можете сохранить 100 документов с пометкой Document1.docx, если они находятся в разных пространствах имен / папках с файлами.

Сеть

Пространства имен также находятся в сетях, как в Интернете, так и в собственной частной внутренней сети компании.Чтобы увидеть, как работает пространство имен домена, подумайте о домене Amazon. Все остальные сайты под ним уникальны. Но как насчет сайтов Amazon в Канаде, Японии или Индии? Для Amazon существуют географические пространства имен, позволяющие однозначно идентифицировать сайты в домене Amazon, но они являются уникальными. На следующем рисунке показан этот сценарий.

Эта установка на самом деле не отличается от примера программирования метода setPrice () в разных пространствах имен. Каждое пространство имен уникально, но может использовать одни и те же имена для страниц под каждым пространством имен.

Краткое содержание урока

В компьютерном программировании пространство имен используется для поддержки функций или процессов с одинаковыми именами. В более крупных системах, таких как системы, охватывающие весь бизнес, несколько программ могут иметь метод setPrice (), который необходимо сохранить в каждом модуле или программе. Пространства имен используются в программировании, включая C / C ++, Java, Visual Basic и C #. Java использует пакетов с той же функциональностью, что и пространство имен.Мы также находим пространства имен в файловых системах, сетевых доменах и в XML документах. Пространства имен используются во всех вычислениях. Их основная функция - группировать связанные объекты и обеспечивать правильную ссылку на нужный объект.

5. Система импорта - документация Python 3.9.5

Код

Python в одном модуле получает доступ к коду в другом модуле
в процессе его импорта. Оператор import выглядит так:
наиболее распространенный способ вызова механизма импорта, но это не единственный
способ.Такие функции, как importlib.import_module () и встроенные
__import __ () также может использоваться для вызова механизма импорта.

Оператор import объединяет две операции; он ищет
названный модуль, затем он связывает результаты этого поиска с именем в локальном
сфера. Операция поиска оператора import определяется как
вызов функции __import __ () с соответствующими аргументами.
Возвращаемое значение __import __ () используется для выполнения имени
операция привязки оператора import .Увидеть
import statement для точных деталей привязки этого имени
операция.

Прямой вызов __import __ () выполняет только поиск модуля и, если
найдено, операция создания модуля. Хотя могут возникнуть определенные побочные эффекты,
такие как импорт родительских пакетов и обновление различных кешей
(включая sys. modules ), только оператор import выполняет
операция привязки имени.

Когда выполняется инструкция import , стандартная встроенная
__import __ () Вызывается функция .Другие механизмы для вызова
система импорта (например, importlib.import_module () ) может выбрать обход
__import __ () и используют собственные решения для реализации семантики импорта.

Когда модуль впервые импортируется, Python ищет модуль и, если он найден,
он создает объект модуля, инициализируя его. Если названный модуль
не может быть найден, возникает ошибка ModuleNotFoundError . Python реализует различные
стратегии поиска названного модуля, когда оборудование импорта
вызван.Эти стратегии можно модифицировать и расширять с помощью различных хуков.
описано в разделах ниже.

Изменено в версии 3.3: Система импорта была обновлена, чтобы полностью реализовать вторую фазу
из ПЭП 302 . Больше не существует механизма неявного импорта - полный
Система импорта представлена ​​через sys. meta_path . Кроме того,
Реализована поддержка пакета собственного пространства имен (см. PEP 420 ).

Модуль importlib предоставляет богатый API для взаимодействия с
система импорта.Например, importlib.import_module () предоставляет
рекомендуется, более простой API, чем встроенный __import __ () для вызова
импортная техника. См. Документацию по библиотеке importlib .
дополнительная деталь.

5.2. Пакеты

Python имеет только один тип объекта модуля, и все модули относятся к этому типу,
независимо от того, реализован ли модуль на Python, C или чем-то еще
еще. Чтобы помочь организовать модули и обеспечить иерархию имен, в Python есть
концепция пакетов.

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

Важно помнить, что все пакеты являются модулями, но не все
модули - это пакеты.Или, другими словами, пакеты - это просто особый вид
модуль. В частности, любой модуль, содержащий атрибут __path__ , является
считается пакетом.

У всех модулей есть имя. Имена подпакетов отделены от родительских
название пакета через точку, что похоже на стандартный синтаксис доступа к атрибутам Python. Таким образом
у вас может быть модуль sys и пакет email ,
который, в свою очередь, имеет подпакет email.mime и модуль внутри
этот подпакет называется электронной почтой .mime.text .

5.2.1. Обычные пакеты

Python определяет два типа пакетов: обычные пакеты и пакеты пространства имен. Обычный
пакеты являются традиционными пакетами, как они существовали в Python 3.2 и ранее.
Обычный пакет обычно реализуется как каталог, содержащий
__init__.py файл. Когда импортируется обычный пакет, это
__init__.py Файл выполняется неявно, и определяемые им объекты
привязаны к именам в пространстве имен пакета.Файл __init__.py может
содержат тот же код Python, который может содержать любой другой модуль, а Python
добавит в модуль некоторые дополнительные атрибуты при его импорте.

Например, следующий макет файловой системы определяет верхний уровень родительского
пакет с тремя подпакетами:

 родитель /
    __init__.py
    один/
        __init__.py
    два/
        __init__.py
    три/
        __init__.py
 

Импорт parent.one неявно выполнит parent / __ init__.py и
родитель / один / __ init__.py . Последующий импорт родительских. Двух или
parent. three выполнит parent / two / __ init__.py и
parent / three / __ init__.py соответственно.

5.2.2. Пакеты пространства имен

Пакет пространства имен состоит из различных частей,
где каждая часть вносит подпакет в родительский пакет. Порции
могут находиться в разных местах файловой системы. Порции также могут быть
найдены в zip-файлах, в сети или в любом другом месте, где Python выполняет поиск
во время импорта.Пакеты пространства имен могут или могут не соответствовать напрямую
объекты в файловой системе; они могут быть виртуальными модулями, не имеющими конкретных
представление.

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

В пакетах пространств имен нет файла parent / __ init__.py . По факту,
во время поиска при импорте может быть найдено несколько родительских каталогов , где
каждый предоставляется другой частью. Таким образом, родитель / один не могут быть
физически расположен рядом с родительским / двумя . В этом случае Python создаст
пакет пространства имен для верхнего уровня родительского пакета всякий раз, когда он или один из
его подпакеты импортируются.

См. Также PEP 420 для спецификации пакета пространства имен.

5.3. В поисках

Чтобы начать поиск, Python нужен полностью квалифицированный
имя модуля (или пакета, но для целей этого обсуждения
разница несущественна) импортируется. Это имя может происходить от разных
аргументы в оператор import или из параметров в
importlib.import_module () или __import __ () функций.

Это имя будет использоваться на различных этапах поиска импорта и может быть
пунктирный путь к подмодулю, e. грамм. foo.bar.baz . В этом случае Python
сначала пытается импортировать foo , затем foo.bar и, наконец, foo.bar.baz .
Если какой-либо из промежуточных операций импорта завершается неудачно, возникает ошибка ModuleNotFoundError .

5.3.1. Модуль cache

Первое место, проверяемое при поиске импорта, - sys.modules . Этот
отображение служит кешем всех модулей, которые были ранее импортированы,
включая промежуточные пути. Итак, если foo.bar.baz ранее был
импортировано, sys.modules будет содержать записи для foo , foo.bar ,
и foo.bar.baz . Каждый ключ будет иметь в качестве значения соответствующий модуль
объект.

Во время импорта имя модуля ищется в sys.modules и если
присутствует, связанное значение - это модуль, удовлетворяющий импорту, а
процесс завершается. Однако, если значение равно Нет , то
ModuleNotFoundError возникает. Если имя модуля отсутствует, Python будет
продолжить поиск модуля.

sys.modules доступен для записи. Удаление ключа не может повредить
связанный модуль (поскольку другие модули могут содержать ссылки на него),
но это сделает запись в кеше для указанного модуля недействительной, что приведет к
Python для нового поиска указанного модуля при его следующем
Импортировать. Ключ также может быть назначен на Нет , что вызовет следующий импорт.
модуля, что приведет к ошибке ModuleNotFoundError .

Однако будьте осторожны, как будто вы сохраняете ссылку на объект модуля,
сделать недействительной запись в кэше sys.modules , а затем повторно импортировать
названный модуль, два объекта модуля будут , а не одинаковыми. Напротив,
importlib.reload () будет повторно использовать тот же объект модуля и просто
повторно инициализировать содержимое модуля, повторно запустив код модуля.

5.

3.2. Искатели и погрузчики

Если названный модуль не найден в sys.модули , затем импорт Python
протокол вызывается для поиска и загрузки модуля. Этот протокол состоит из
два концептуальных объекта, искатели и загрузчики.
Задача поисковика - определить, сможет ли он найти названный модуль, используя
какую бы стратегию он ни знал. Объекты, реализующие оба этих
интерфейсы называются импортерами - они возвращают
сами, когда обнаруживают, что могут загрузить запрошенный модуль.

Python включает ряд средств поиска и импорта по умолчанию. Первый
знает, как найти встроенные модули, а второй знает, как найти
замороженные модули.Третий поисковик по умолчанию ищет путь импорта
для модулей. Путь импорта - это список мест, которые могут
имена путей файловой системы или zip-файлов. Его также можно расширить для поиска
для любого доступного ресурса, например для тех, которые определены URL-адресами.

Импортное оборудование является расширяемым, поэтому могут быть добавлены новые средства поиска для расширения
диапазон и объем поиска модуля.

Finders фактически не загружают модули. Если им удастся найти названный модуль, они
вернуть спецификацию модуля , инкапсуляцию модуля, относящегося к импорту
информация, которую затем использует механизм импорта при загрузке модуля.

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

Изменено в версии 3.4: в предыдущих версиях Python средства поиска возвращали загрузчики.
напрямую, тогда как теперь они возвращают спецификации модулей, которые содержат загрузчиков.
Загрузчики по-прежнему используются во время импорта, но несут меньшую ответственность.

5.3.3. Крючки импортные

Импортное оборудование разработано с возможностью расширения; основной механизм для
это импортные крючки .Есть два типа перехватчиков импорта: мета
хуки
и импортируют хуки пути .

Мета-хуки вызываются в начале обработки импорта, перед любыми другими
Произошла обработка импорта, кроме sys.modules поиск в кэше .
Это позволяет мета-хукам отменять обработку sys.path , заморожено
модули или даже встроенные модули. Мета-хуки регистрируются путем добавления новых
поисковые объекты к sys.meta_path , как описано ниже.

Перехватчики пути импорта вызываются как часть sys.путь (или
package .__ path__ ) в точке, где их связанный путь
элемент встречается. Перехватчики пути импорта регистрируются путем добавления новых вызываемых объектов
к sys.path_hooks , как описано ниже.

5.3.4. Мета-путь

Когда названный модуль не найден в sys.modules , Python следующий
выполняет поиск sys.meta_path , который содержит список средств поиска мета-пути
объекты. Эти искатели опрашиваются, чтобы узнать, знают ли они, как обрабатывать
названный модуль. Поисковики мета-пути должны реализовать метод, называемый
find_spec () , который принимает три аргумента:
имя, путь импорта и (необязательно) целевой модуль. Мета-путь
Finder может использовать любую стратегию, чтобы определить, может ли он обрабатывать
названный модуль или нет.

Если средство поиска мета-пути знает, как обращаться с указанным модулем, оно возвращает
объект спецификации. Если он не может обработать указанный модуль, он возвращает Нет . Если
sys.meta_path обработка достигает конца своего списка без возврата
спецификации, то возникает ModuleNotFoundError .Любые другие исключения
поднятые просто распространяются вверх, прерывая процесс импорта.

Метод find_spec () мета-пути
Finders вызывается с двумя или тремя аргументами. Первый - это полностью
полное имя импортируемого модуля, например foo.bar.baz .
Второй аргумент - это записи пути, используемые для поиска модуля. Для
модулей верхнего уровня, второй аргумент - Нет , но для подмодулей или
подпакетов, второй аргумент - это значение родительского пакета
__path__ атрибут.Если соответствующий атрибут __path__ не может
будет вызван ModuleNotFoundError . Третий аргумент
- это существующий объект модуля, который будет загружен позже.
Система импорта передает целевой модуль только во время перезагрузки.

Мета-путь может быть пройден несколько раз для одного запроса на импорт.
Например, предполагая, что ни один из задействованных модулей еще не был кэширован,
импорт foo.bar.baz сначала выполнит импорт верхнего уровня, вызывая
миль на фут.find_spec ("foo", None, None) для каждого средства поиска мета-пути ( mpf ). После
foo было импортировано, foo.bar будет импортировано путем обхода
мета-путь во второй раз, вызывая
mpf.find_spec ("foo.bar", foo .__ path__, None) . После того, как foo.bar был
импортировано, окончательный обход вызовет
mpf.find_spec ("foo.bar.baz", foo.bar .__ path__, None) .

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

Python по умолчанию sys.meta_path имеет три средства поиска мета-пути, один из которых
умеет импортировать встроенные модули, умеет импортировать замороженные
модули, и тот, который знает, как импортировать модули из пути импорта
(т.е. искатель на основе пути).

Изменено в версии 3.4: Метод find_spec () мета-пути
finders заменили find_module () , который
теперь устарела. Пока он будет продолжать работать без изменений,
импортная техника будет пробовать это только в том случае, если искатель не реализует
find_spec () .

5.4. Загрузка

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

 модуль = Нет
если spec.loader не равен None и hasattr (spec.loader, 'create_module'):
    # Предполагается, что exec_module также будет определен в загрузчике.
    module = spec.loader.create_module (спецификация)
если модуль None:
    module = ModuleType (спец.название)
# Здесь устанавливаются атрибуты модуля, связанные с импортом:
_init_module_attrs (спецификация, модуль)

если spec.loader - Нет:
    # не поддерживается
    поднять ImportError
если spec.origin равен None и spec.submodule_search_locations не равен None:
    # пакет пространства имен
    sys.modules [spec.name] = модуль
elif not hasattr (spec.loader, 'exec_module'):
    module = spec.loader.load_module (spec.name)
    # Установите __loader__ и __package__, если они отсутствуют.
еще:
    sys.modules [spec.name] = модуль
    пытаться:
        спец. загрузчик.exec_module (модуль)
    кроме BaseException:
        пытаться:
            del sys.modules [имя спецификации]
        кроме KeyError:
            проходить
        поднимать
вернуть sys.modules [spec.name]
 

Обратите внимание на следующие данные:

  • Если существует объект модуля с данным именем в
    sys.modules , импорт уже вернул его.

  • Модуль будет существовать в sys.modules перед загрузчиком
    выполняет код модуля.Это очень важно, потому что код модуля может
    (прямо или косвенно) сам импорт; добавив его в sys.modules
    заранее предотвращает неограниченную рекурсию в худшем случае и множественные
    загрузка в лучшем виде.

  • Если загрузка не удалась, неисправный модуль - и только неисправный модуль -
    удаляется из sys.modules . Любой модуль уже в
    sys.modules cache и любой успешно загруженный модуль
    как побочный эффект, он должен оставаться в кеше.Это контрастирует с
    перезагрузка, когда даже неисправный модуль остается в sys.modules .

  • После создания модуля, но перед выполнением, механизм импорта
    устанавливает атрибуты модуля, связанные с импортом («_init_module_attrs» в
    пример псевдокода выше), как показано в
    более поздний раздел.

  • Выполнение модуля - ключевой момент загрузки, при котором модуль
    пространство имен заполняется. Исполнение полностью делегировано
    загрузчик, который решает, что и как заполнять.

  • Модуль, созданный во время загрузки и переданный в exec_module (), может
    не будет возвращенным в конце импорта.

Изменено в версии 3.4: система импорта взяла на себя стандартные обязанности
погрузчики. Ранее они выполнялись
importlib.abc.Loader.load_module () метод.

5.4.1. Погрузчики

Загрузчики модулей обеспечивают важнейшую функцию загрузки: выполнение модуля.
Импортное оборудование вызывает importlib.abc.Loader.exec_module ()
с одним аргументом, объект модуля для выполнения. Любое значение
возвращается из exec_module () игнорируется.

Погрузчики

должны удовлетворять следующим требованиям:

  • Если модуль является модулем Python (в отличие от встроенного модуля или
    динамически загружаемое расширение), загрузчик должен выполнить код модуля
    в глобальном пространстве имен модуля ( module .__ dict__ ).

  • Если загрузчик не может выполнить модуль, он должен поднять
    ImportError , хотя во время
    exec_module () будет распространяться.

Во многих случаях искатель и загрузчик могут быть одним и тем же объектом; в таких случаях
find_spec () просто вернет
spec с загрузчиком, установленным на self .

Загрузчики модулей могут разрешить создание объекта модуля во время загрузки.
путем реализации метода create_module () .
Он принимает один аргумент, спецификацию модуля, и возвращает новый объект модуля.
использовать во время загрузки. create_module () не требует установки каких-либо атрибутов
на объекте модуля.Если метод возвращает None ,
импортное оборудование само создаст новый модуль.

Изменено в версии 3.4: Метод load_module () заменен на
exec_module () и импорт
Машины взяли на себя все стандартные обязанности по погрузке.

Для совместимости с существующими погрузчиками импортная техника будет использовать
метод загрузчиков load_module () , если он существует и загрузчик делает
не реализовывать также exec_module () .Однако load_module () был
устарело, и загрузчики должны вместо этого реализовать exec_module () .

Метод load_module () должен реализовывать всю стандартную загрузку
функциональность, описанная выше, в дополнение к выполнению модуля. Все
применяются те же ограничения с некоторыми дополнительными пояснениями:

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

  • Модуль должен существовать в sys.modules перед загрузчиком
    выполняет код модуля, чтобы предотвратить неограниченную рекурсию или множественные
    загрузка.

  • Если загрузка не удалась, загрузчик должен удалить все вставленные модули.
    в систем.модули , но он должен удалить только неисправный
    модуль (-ы), и только если загрузчик сам загрузил модуль (-ы)
    явно.

Изменено в версии 3.5: DeprecationWarning возникает, когда определено exec_module () , но
create_module () - нет.

Изменено в версии 3.6: ImportError возникает, когда определено exec_module () , но
create_module () - нет.

5.4.2. Субмодули

Когда подмодуль загружается с использованием любого механизма (например, importlib API),
импорт или импорт из операторов или встроенный __import __ () ) a
привязка помещается в пространство имен родительского модуля к объекту подмодуля.
Например, если в пакете spam есть подмодуль foo , после импорта
spam.foo , spam будет иметь атрибут foo , который привязан к
подмодуль.Допустим, у вас есть следующая структура каталогов:

 спам /
    __init__.py
    foo.py
    bar.py
 

и spam / __ init__.py содержит следующие строки:

 из .foo import Foo
из .bar import Bar
 

, затем выполнение следующего помещает привязку имени к foo и bar в
спам модуль:

 >>> импортировать спам
>>> spam.foo
<модуль 'spam.foo' из '/ tmp / imports / spam / foo.py '>
>>> spam.bar
<модуль 'spam.bar' из '/tmp/imports/spam/bar.py'>
 

Учитывая знакомые правила привязки имен Python, это может показаться удивительным, но
на самом деле это фундаментальная особенность системы импорта. Инвариант
удержание заключается в том, что если у вас есть sys.modules ['spam'] и
sys.modules ['spam.foo'] (как после вышеупомянутого импорта), последний
должен появиться как атрибут foo первого.

5.4.3. Спецификация модуля

Импортное оборудование использует различную информацию о каждом модуле.
во время импорта, особенно перед загрузкой.Большая часть информации
общий для всех модулей. Цель спецификации модуля - инкапсулировать
эта информация, связанная с импортом, для каждого модуля.

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

Спецификация модуля представлена ​​как атрибут __spec__ в объекте модуля.
См. ModuleSpec для получения подробной информации о содержании
спецификация модуля.

5.4.5. модуль .__ путь__

По определению, если модуль имеет атрибут __path__ , это пакет.

Атрибут __path__ пакета используется во время импорта его подпакетов.
Внутри механизма импорта он работает так же, как sys.path ,
я.е. предоставление списка мест для поиска модулей во время импорта.
Однако __path__ обычно гораздо более ограничен, чем
sys.path .

__path__ должен быть итеративным из строк, но может быть пустым.
Те же правила, что и для sys.path , также применяются к пакетам
__path__ и sys.path_hooks (описано ниже)
консультируется при обходе пакета __path__ .

__init__ пакета.Файл py может устанавливать или изменять __path__ пакета
атрибут, и это обычно был способ реализации пакетов пространства имен
до PEP 420 . С принятием PEP 420 пакеты пространства имен не
больше необходимо предоставить __init__.py файлов, содержащих только __path__
код манипуляции; механизм импорта автоматически устанавливает __path__
правильно для пакета пространства имен.

5.4.6. Модуль reprs

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

Если у модуля есть спецификация ( __spec__ ), механизм импорта попытается
чтобы сгенерировать репорт из него. Если это не удается или спецификации нет, импорт
система создаст репорт по умолчанию, используя любую доступную информацию
на модуле. Он попытается использовать модуль .__ name__ ,
module .__ file__ и module .__ loader__ в качестве входных данных в repr,
со значениями по умолчанию для любой информации, которая отсутствует.

Вот точные используемые правила:

  • Если модуль имеет атрибут __spec__ , информация в спецификации
    используется для создания репр.«Имя», «загрузчик», «происхождение» и
    Консультируются с атрибутами «has_location».

  • Если модуль имеет атрибут __file__ , он используется как часть
    репр. модуля

  • Если в модуле нет __file__ , но есть __loader__ , которого нет
    Нет , тогда repr загрузчика используется как часть repr модуля.

  • В противном случае просто используйте __name__ модуля в репр.

Изменено в версии 3.4: Использование loader.module_repr ()
устарел, и теперь спецификация модуля используется при импорте
машины для генерации модуля репр.

Для обратной совместимости с Python 3.3 репер модуля будет
генерируется путем вызова загрузчика
module_repr () метод, если он определен, прежде
пробуя любой подход, описанный выше. Однако этот метод устарел.

5.4.7. Аннулирование кешированного байт-кода

Перед тем, как Python загрузит кешированный байт-код из файла .pyc , он проверяет,
cache обновлен с исходным файлом .py . По умолчанию Python делает это
сохраняя метку времени и размер последнего изменения источника в файле кеша, когда
писать это. Во время выполнения система импорта затем проверяет файл кеша с помощью
проверка сохраненных метаданных в файле кеша на соответствие исходному
метаданные.

Python также поддерживает файлы кэша «на основе хэша», в которых хранится хэш исходного кода.
содержимое файла, а не его метаданные. Есть два варианта хеширования
.Файлы pyc : отмечены и не отмечены. Для проверенных хеш-файлов .pyc ,
Python проверяет файл кеша, хешируя исходный файл и сравнивая
полученный хеш с хешем в файле кеша. Если проверенный кеш на основе хеша
файл оказывается недействительным, Python восстанавливает его и записывает новый проверенный
Кэш-файл на основе хэша. Для непроверенных хеш-файлов .pyc Python просто
предполагает, что файл кеша действителен, если он существует. файлов .pyc на основе хэша файлов
поведение проверки можно переопределить с помощью --check-hash-based-pycs
флаг.

Изменено в версии 3.7: Добавлены хеш-файлы .pyc . Раньше Python поддерживал только
недействительность кешей байт-кода на основе временных меток.

5.5. Поиск на основе пути

Как упоминалось ранее, Python поставляется с несколькими поисковиками мета-пути по умолчанию.
Один из них, называемый поиском пути
( PathFinder ), ищет путь импорта,
который содержит список записей пути. Каждый путь
запись указывает место для поиска модулей.

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

Набор по умолчанию средств поиска входов пути реализует всю семантику для поиска
модули в файловой системе, обрабатывающие специальные типы файлов, такие как исходный код Python
код ( файлов .py, ), байтовый код Python ( файлов .pyc, ) и
разделяемые библиотеки (например, .so файлов). При поддержке zipimport
модуль в стандартной библиотеке, средства поиска путей по умолчанию также обрабатывают
загрузка всех этих типов файлов (кроме общих библиотек) из zip-файлов.

Записи пути не должны ограничиваться местоположениями файловой системы. Они могут ссылаться на
URL-адреса, запросы к базе данных или любое другое местоположение, которое можно указать как
нить.

Средство поиска на основе пути предоставляет дополнительные перехватчики и протоколы, чтобы вы
может расширять и настраивать типы записей пути с возможностью поиска. Например,
если вы хотите поддерживать записи пути как сетевые URL-адреса, вы можете написать ловушку
который реализует семантику HTTP для поиска модулей в Интернете. Этот крючок (а
callable) вернет средство поиска записи пути, поддерживающее протокол
описанный ниже, который затем был использован для загрузки загрузчика модуля из
Интернет.

Предупреждение: в этом и предыдущем разделе используется термин finder ,
различая их, используя термины "поиск мета-пути" и
поиск пути входа. Эти два типа искателей очень похожи,
поддерживают аналогичные протоколы и работают одинаково во время импорта
процесс, но важно помнить, что они немного отличаются.
В частности, поисковики мета-пути работают в начале импорта.
процесс, как указано в обходе sys.meta_path .

В отличие от этого, средства поиска входа в путь в некотором смысле являются деталью реализации.
искателя на основе пути, и на самом деле, если бы искатель на основе пути был
удалено из sys.meta_path , нет семантики поиска записи пути
будет вызван.

5.5.1. Поиск путей

Искатель пути отвечает за поиск и загрузку
Модули и пакеты Python, расположение которых указано строкой
запись пути. Большинство записей пути обозначают местоположения в файловой системе,
но они не должны ограничиваться этим.

В качестве средства поиска мета-пути средство поиска на основе пути реализует
find_spec () протокол ранее
описан, однако он предоставляет дополнительные крючки, которые можно использовать для
настроить способ поиска и загрузки модулей из пути импорта.

При поиске пути используются три переменные: sys.path ,
sys.path_hooks и sys.path_importer_cache . __path__
также используются атрибуты объектов пакета. Они предоставляют дополнительные способы
что импортная техника может быть настроена.

sys.path содержит список строк, обеспечивающих поиск местоположения для
модули и пакеты. Он инициализируется из PYTHONPATH
переменная среды и различные другие установки и
значения по умолчанию, зависящие от реализации. Записи в sys.path могут называть
каталоги в файловой системе, zip-файлы и, возможно, другие «места»
(см. модуль сайта ), в которых следует искать модули, такие как
URL-адреса или запросы к базе данных. На нем должны присутствовать только строки и байты.
систем.путь ; все остальные типы данных игнорируются. Кодировка байтов
записей определяется поисковиками отдельных путей.

Средство поиска на основе пути - это средство поиска мета пути, поэтому импорт
механизм начинает поиск пути импорта с вызова пути
на основе метода поиска find_spec () как
описано ранее. Когда путь аргумент к
find_spec () дано, это будет
список строковых путей для обхода - обычно это пакет __path__
атрибут для импорта в этом пакете.Если аргумент path равен
Нет , это указывает на импорт верхнего уровня и используется sys.path .

Средство поиска на основе пути перебирает каждую запись в пути поиска, и
для каждого из них ищет соответствующий поиск путей входа
( PathEntryFinder ) для
запись пути. Поскольку это может быть дорогостоящая операция (например, может быть
stat () накладных расходов на вызов для этого поиска), поиск на основе пути поддерживает
записи пути сопоставления кэша средствам поиска записей пути.Этот кеш поддерживается
в sys.path_importer_cache (несмотря на название, этот кеш на самом деле
хранит объекты поиска, а не ограничивается объектами-импортерами).
Таким образом, дорогостоящий поиск определенной записи пути
поиск пути к местоположению нужно выполнить только один раз. Код пользователя
бесплатно для удаления записей кеша из sys.path_importer_cache принудительного
поисковик на основе пути, чтобы снова выполнить поиск записи пути.

Если запись пути отсутствует в кэше, поисковик на основе пути выполняет итерацию
по каждому вызываемому в sys.path_hooks . Каждая запись пути
хуки в этом списке вызываются с одним аргументом,
запись пути для поиска. Этот вызываемый объект может либо возвращать путь
поисковик, который может обрабатывать запись пути, или может вызвать
ImportError . ImportError используется средством поиска на основе пути для
сигнал о том, что ловушка не может найти средство поиска пути
для этой записи пути. В
исключение игнорируется, и итерация пути импорта продолжается. Крюк
следует ожидать либо строковый, либо байтовый объект; кодирование байтовых объектов
до крючка (e.грамм. это может быть кодировка файловой системы, UTF-8 или что-то еще
else), и если ловушка не может декодировать аргумент, она должна поднять
ImportError .

Если sys.path_hooks итерация заканчивается без поиска записи пути
возвращается, то поисковик на основе пути
find_spec () метод сохранит None
в sys.path_importer_cache (чтобы указать, что нет средства поиска для
эта запись пути) и вернуть None , указывая, что это
поисковику мета-пути не удалось найти модуль.

Если средство поиска записи пути - это , возвращенное одной из записей пути
перехватить callables на sys.path_hooks , тогда используется следующий протокол
чтобы запросить у средства поиска спецификацию модуля, которая затем используется при загрузке
модуль.

Текущий рабочий каталог - обозначается пустой строкой - обрабатывается
немного отличается от других записей на sys.path . Во-первых, если
текущий рабочий каталог не существует, значение не сохраняется в
систем.path_importer_cache . Во-вторых, значение текущего рабочего
каталог просматривается свежим для каждого поиска модуля. В-третьих, путь, используемый для
sys.path_importer_cache и возвращено
importlib.machinery.PathFinder.find_spec () будет фактическим текущим
рабочий каталог, а не пустая строка.

5.5.2. Протокол поиска входа в путь

Для поддержки импорта модулей и инициализированных пакетов, а также для
вносить части в пакеты пространства имен, средства поиска путей должны реализовывать
метод find_spec () .

find_spec () принимает два аргумента:
полное имя импортируемого модуля и (необязательно) цель
модуль. find_spec () возвращает полностью заполненную спецификацию для модуля.
В этой спецификации всегда будет установлен «загрузчик» (за одним исключением).

Чтобы указать машине импорта, что спецификация представляет собой пространство имен
часть, средство поиска записи пути устанавливает «submodule_search_locations» равным
список, содержащий часть.

Изменено в версии 3.4: find_spec () заменено
find_loader () и
find_module () , оба из которых
теперь устарели, но будут использоваться, если find_spec () не определено.

Старые средства поиска путей доступа могут реализовать один из этих двух устаревших методов
вместо find_spec () . Методы по-прежнему соблюдаются
ради обратной совместимости. Однако, если find_spec () - это
реализовано в поисковике записи пути, устаревшие методы игнорируются.

find_loader () принимает один аргумент,
полное имя импортируемого модуля. find_loader ()
возвращает 2-кортеж, где первый элемент является загрузчиком, а второй элемент
является частью пространства имен.

Для обратной совместимости с другими реализациями импорта
протокол, многие средства поиска входов пути также поддерживают то же самое,
традиционный метод find_module () , поддерживаемый поисковиками мета-пути.
Однако методы поиска пути find_module () никогда не вызываются.
с аргументом path (ожидается, что они будут записывать соответствующий
информация о пути от первоначального вызова к перехватчику пути).

Метод find_module () в средствах поиска записи пути устарел,
так как это не позволяет поисковику входа пути вносить части в
пакеты пространства имен. Если и find_loader () , и find_module ()
существуют в поисковике записи пути, система импорта всегда будет вызывать
find_loader () вместо find_module () .

5,6. Замена стандартной системы импорта

Самый надежный механизм замены всей системы импорта - это
удалите содержимое по умолчанию sys.meta_path , заменив их
полностью с настраиваемым перехватчиком мета-пути.

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

Для выборочного предотвращения импорта некоторых модулей из перехвата на ранней стадии
мета-путь (вместо полного отключения стандартной системы импорта),
достаточно поднять ModuleNotFoundError прямо из
find_spec () вместо возврата
Нет .Последнее указывает на то, что поиск мета-пути должен продолжаться,
при возникновении исключения оно немедленно прекращается.

5,7. Относительный импорт пакетов

Относительный импорт использует начальные точки. Одиночная точка в начале указывает на относительную
import, начиная с текущего пакета. Две или более ведущих точек обозначают
относительный импорт к родителю (ам) текущего пакета, один уровень на точку
после первого. Например, при следующем макете упаковки:

 упаковка /
    __в этом__.ру
    подпакет1 /
        __init__.py
        moduleX.py
        moduleY.py
    подпакет2 /
        __init__.py
        moduleZ.py
    moduleA.py
 

В подпакете 1 / moduleX.py или подпакете1 / __ init__.py ,
следующие допустимые относительные импорт:

 из .moduleY импортировать спам
из .moduleY импортировать спам как ветчину
из . модуль импортаY
from ..subpackage1 import moduleY
from ..subpackage2.moduleZ импортировать яйца
from ..moduleA import foo
 

Абсолютный импорт может использовать либо import <> , либо из <> import <>
синтаксис, но относительный импорт может использовать только вторую форму; причина
для этого то:

должен выставить XXX.YYY.ZZZ в качестве полезного выражения, но .moduleY
недействительное выражение.

5,8. Особые рекомендации для __main__

Модуль __main__ - это особый случай по сравнению с импортом Python.
система. Как отмечено в другом месте, модуль __main__
инициализируется непосредственно при запуске интерпретатора, как sys и
встроенных . Однако, в отличие от этих двух, это не совсем
квалифицируются как встроенный модуль. Это потому, что способ, которым
__main__ инициализируется в зависимости от флагов и других параметров с
который вызывается интерпретатором.

5.8.1. __машина __.__ spec__

В зависимости от того, как инициализируется __main__ , __main __.__ spec__
устанавливается соответствующим образом или на Нет .

Когда Python запускается с опцией -m , устанавливается __spec__
к спецификации соответствующего модуля или пакета. __spec__ - это
также заполняется, когда модуль __main__ загружается как часть выполнения
каталог, zip-файл или другой sys.путь запись.

В остальных случаях
__main __.__ spec__ установлен на None , так как код, используемый для заполнения
__main__ не соответствует напрямую импортируемому модулю:

Обратите внимание, что __main __.__ spec__ всегда равно None в последнем случае,
, даже если файл технически может быть импортирован напрямую как модуль
вместо. Используйте переключатель -m , если требуются допустимые метаданные модуля.
в __main__ .

Обратите внимание, что даже если __main__ соответствует импортируемому модулю
и __main __.__ spec__ установлено соответственно, они по-прежнему считаются
отдельных модулей. Это связано с тем, что блоки охраняются
if __name__ == "__main__": проверки выполняются только при использовании модуля
для заполнения пространства имен __main__ , а не во время обычного импорта.

5,9. Открытые выпуски

XXX Было бы здорово иметь схему.

XXX * (import_machinery.rst) как насчет раздела, посвященного только
атрибуты модулей и пакетов, возможно, расширяющие или заменяющие
связанные записи на справочной странице модели данных?

XXX runpy, pkgutil и другие в руководстве по библиотеке должны получить «См. Также»
ссылки вверху, указывающие на раздел новой системы импорта.

XXX Добавьте дополнительные пояснения относительно различных способов, которыми
__main__ инициализирован?

XXX Добавьте дополнительную информацию о __main__ причудах / подводных камнях (т.е. копировать из
PEP 395 ).

5.10. Список литературы

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

Исходная спецификация для sys.meta_path была PEP 302 , с
последующее расширение в PEP 420 .

PEP 420 представил пакеты пространства имен для
Python 3.3. PEP 420 также представил протокол find_loader () как
альтернатива find_module () .

PEP 366 описывает добавление атрибута __package__ для
явный относительный импорт в основных модулях.

PEP 328 ввел абсолютный и явный относительный импорт и первоначально
предложено __name__ для семантики PEP 366 в конечном итоге будет указывать для
__пакет__ .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *