PythonとC++の名前空間を比較するには?using宣言とimportの違いを解説
PythonとC++の名前空間は、仕組みが根本的に異なるため、単純に一対一で比較できるものではありません。それぞれの言語における「名前の扱い方」の違いを、具体的なコード例を交えて見ていきましょう。
C++のusing宣言:ns::AをAだけで書けるようにする
まず、C++で次のようなヘッダーファイルがあるとします。
// a.h
namespace ns {
struct A { /* ... */ };
struct B { /* ... */ };
}
ここで、次のようにusing宣言を使った場合:
#include "a.h"
using ns::A;
このコードの目的は、Aを名前空間の修飾なしで(つまりns::Aと書かずにAだけ記述して)使えるようにすることです。
Pythonのfrom-importとの決定的な違い
これを見て、「Pythonならこう書けば同じでは?」と考えるかもしれません。
from a import A
しかし、この2つには重要な違いがあります。C++の#includeはヘッダーファイルの中身をそのまま展開する処理なので、using宣言の有無にかかわらず、a.h全体がコンパイル対象になります。したがって、ns::Bも引き続き問題なく利用できます。
一方、Pythonのfrom a import Aは、モジュールaからAという名前だけを現在の名前空間へ取り込む操作です。この場合、a.Bという形でもBにはアクセスできない点に注意が必要です(Bを使いたければ、改めてfrom a import Bとする必要があります)。
using namespaceディレクティブに対応するPython構文はない
もうひとつのC++の書き方である、次のusingディレクティブ:
using namespace ns;
これは、名前空間ns内のすべての名前をコードベース全体に取り込むものであり、Pythonには直接対応する構文が存在しません。さらにC++の名前空間は、複数のヘッダーにまたがって再利用(拡張)できるのも大きな特徴です。例えば、標準ライブラリでは次のような使い方がよく見られます。
#include <vector>
#include <map>
#include <algorithm>
using namespace std; // std内のすべてを取り込む
この1行の「動作」だけに着目すれば、Pythonのワイルドカードインポートに近いと言えるでしょう。
from vector import *
from map import *
from algorithm import *
ただし厳密には異なり、using namespace std;が取り込むのはstd名前空間に属する名前だけです。ヘッダーに含まれるすべての定義が対象になるわけではありません。
まとめ
- C++の
using ns::A;(using宣言)は特定の名前だけを修飾なしで使えるようにするが、ヘッダー自体は丸ごとインクルードされるため、ns::Bのような他の名前も引き続き利用可能。 - Pythonの
from a import Aは指定した名前のみを取り込むため、a.Bは参照できない。 - C++の
using namespace ns;(usingディレクティブ)は名前空間全体を取り込むが、Pythonには正確に対応する構文がなく、import *が最も近いものの挙動は一致しない。
このように、両者は表面的に似た構文を持っていても、インクルードとインポートという内部的な仕組みそのものが異なるため、単純な対応関係として捉えるのは避けるのが賢明です。
-
C++で組み合わせと順列を計算する方法をわかりやすく解説
組み合わせと順列とは組み合わせ(Combination)と順列(Permutation)は、数学の一分野である組合せ論(Combinatorics)に属する概念です。順列とは、n個の要素の中から、1つずつ・いくつかずつ・あるいはすべてを一度に取り出して並べるときの、異なる並び方の総数のことです。並べる順序が結果に影響する点が特徴です。一方、組み合わせとは、同じくn個の要素から1つずつ・いくつかずつ・すべてを取り出して選ぶときの、異なる選び方の総数です。順序は考慮されないため、順列よりも数が少なくなります。計算式順列の数n個の要素全体からr個の要素を並べるときの順列の数は、次の公式で求められます
-
Pythonの名前空間とスコープの仕組みをわかりやすく解説
Pythonでは、変数・関数・ライブラリ・モジュールなど、さまざまな「名前」を扱います。ところが、使おうとした変数名が、すでに別の変数や関数、メソッドの名前として存在している――そんな場面に遭遇することは珍しくありません。このような名前の衝突を避けるためにも、Pythonがこれらの名前をどのように管理しているのかを理解しておく必要があります。その鍵となるのが「名前空間(namespace)」という概念です。 名前空間の3つの種類 Pythonの名前空間は、大きく次の3つに分類されます。 ローカル名前空間(Local Namespace)関数の中で定義された変数や関数の名前を保持する名前空