Pythonのジェネレータは、関数のreturnの箇所をyieldに変えることで作成できます。ジェネレータは関数の呼び出しから次の呼び出しの間、その関数におけるローカルの変数を保持したまま処理を中断して待機します。
def generator():
    for i in range(3):
        yield i
生成したジェネレータをnext()の引数に指定して、逐次的に要素を取り出すことができます。
gen = generator()
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 2
ジェネレータは、素数などの無限数列の要素を逐次的に取り出すような処理が可能になります。
一方、Pythonのopen関数は、ファイルを開くための組み込み関数です。open関数を使用してファイルを開くと、そのファイルを操作するためのファイルオブジェクトが返されます。ファイルオブジェクトは、ジェネレータの一種と考えることもできます。なぜなら、ファイルオブジェクトはイテレータプロトコルを実装しているからです。つまり、ファイルオブジェクトもfor文などで逐次的に要素を取り出すことができます。
with open('file.txt', 'r') as f:
    for line in f:
        print(line)
このコードは、’file.txt’という名前のファイルを開き、その中の各行を順に出力します。ここで、ファイルオブジェクトfはジェネレータのように振る舞い、ファイルの各行を逐次的に生成します。
以上がPythonのジェネレータとopen関数の基本的な使い方とその関連性についての説明です。これらの概念を理解することで、Pythonのコードをより効率的に書くことができます。