Пространство имен 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.
В программе на языке Си имена (идентификаторы) используются для ссылок на различного рода объекты — функции, переменные, формальные параметры и т. Чтобы различать идентификаторы объектов различного рода, компилятор языка Си устанавливает так называемые «пространства имен». Во избежание противоречий имена внутри одного пространства должны быть уникальными, однако в различных пространствах могут содержаться идентичные имена. Это означает, что можно использовать один и тот же идентификатор для двух или более различных объектов, если имена объектов принадлежат к различным пространствам. Однозначное разрешение вопроса о том, на какой объект ссылается идентификатор, компилятор языка Си осуществляет по контексту появления данного идентификатора в программе. Ниже перечисляются виды объектов, которые можно именовать в программе на языке Си, и соответствующие им четыре пространства имен.
Пример : struct student В этом примере имя тега структуры, элемента структуры и самой структуры относится к трем различным пространствам имен, поэтому не возникает противоречия между тремя объектами с одинаковым именем student. Компилятор языка Си определит по контексту использования, на какой из объектов ссылается идентификатор в каждом конкретном случае. Например, когда идентификатор student появится после ключевого слова struct, это будет означать, что именуется тег структуры. Когда идентификатор 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, которые передают события друг другу.«События - это такие вещи, как подключение общего сетевого ресурса или размонтирование оптического устройства. Почему это важно, спросите вы? Что ж, когда дело доходит до пространства имен монтирования, группы равноправных узлов , часто являются решающим фактором относительно того, нужно ли монтировать виден и с ним можно взаимодействовать. Состояние монтирования определяет, может ли член в одноранговой группе получить событие. Согласно той же документации ядра, существует пять состояний монтирования:
- общий - монтирование, которое принадлежит одноранговой группе.Любые происходящие изменения будут распространяться на всех членов одноранговой группы.
- slave - Одностороннее распространение.
Главная точка монтирования будет распространять события на ведомое устройство, но ведущее устройство не будет видеть никаких действий, предпринимаемых ведомым устройством.
- общий и подчиненный - указывает, что точка монтирования имеет главный сервер, но также имеет свою собственную группу одноранговых узлов. Мастер не будет уведомлен об изменениях точки монтирования, но все члены группы одноранговых узлов, расположенные ниже по потоку, будут.
- частный - не получает и не пересылает никаких событий распространения.
- 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-код содержит информацию о предмете мебели:
Пространства имен в реальном использовании
XSLT - это язык, который можно использовать для преобразования XML-документов в другие форматы.
XML-документ ниже - это документ, используемый для преобразования XML в HTML.
Пространство имен http://www.w3.org/1999/XSL/Transform определяет XSLT
элементы внутри HTML-документа:
"?>
xmlns: xsl = "http://www.w3.org/1999/XSL/Transform">
Моя коллекция компакт-дисков
Заголовок | Художник |
---|---|
| |
xsl: template>
xsl: stylesheet>
Если вы хотите узнать больше о 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 в конечном итоге будет указывать для
__пакет__
.