「○○作って」だけがAIの使い方ではない
妻などに生成Aiが便利という話をしてもピンとこないようだ。たぶん、一般的にそうなのだろう。
生成AIというと文章を作ってくれるとか、プログラムを代わりに作ってくれるというのが主たるイメージだと思うけれど、自分的に役立つのは”相談役”である。
仕事をしていて「ん~?」ということについて調べるのに使うということである。
そんなことはググって調べればよかろうと思っていたのだけれど、生成AIに聞いたほうが早い場合が多い。
例えば私はPythonというプログラミング言語はど素人レベル。 プログラムを作っていて、初期処理を書きたかった。初期処理というのは起動時に強制的に行われるような処理で、プログラミング言語ごとに独特の作法というものがある。
BasicならPrivate sub initialize()・・のようにである。
Pythonならdef __init__であることは頭の片隅にあった。
最近の開発環境・・・プログラム自体はただのテキストなので、メモ帳とかでも書ける。ただ、それより書きやすいように色分けしたり、予測入力してくれたりする機能を持ったプログラミング専用のメモ帳ソフトのこと・・・でdef __init__と打ち込むと、勝手に
def __init__(self) -> None: ${0:pass}
と出る。${0:pass}はエラーになっているし、意味の分からんところがある。
これについて調べようと思ったら、「Python ->」とかでググるんだろうけど、これで正解に辿り着くのは結構大変だ。
そこでAIに聞く。
Pythonの def init(self) -> None: という行について解説して。
Pythonのクラスは、__init__()
という特殊なメソッドを定義することができます。このメソッドは、クラスのインスタンスが作成されるときに自動的に呼び出されます。 __init__()
メソッドは、インスタンス変数の初期化や、必要な処理の設定を行うために使用されます。特に、self
パラメータは、そのクラスのインスタンス自体を参照するための引数です。このself
パラメータを介して、インスタンス変数を定義したり、他のメソッドを呼び出したりすることができます。 __init__()
メソッドは通常、以下のように定義されます。
def __init__(self):
# インスタンス変数の初期化や処理の設定
__init__()
メソッドは何も返さないため、-> None
として返り値の型を指定しています。 例えば、以下のようなクラスを考えてみましょう。
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
def print_values(self):
print("x:", self.x)
print("y:", self.y)
このクラスでは、__init__()
メソッドでself.x
とself.y
のインスタンス変数の初期化を行っています。インスタンスが作成されるときには、引数として指定された値がself.x
とself.y
に設定されます。
my_object = MyClass(10, 20)
my_object.print_values()
上記のコードでは、my_object
という名前のMyClass
のインスタンスを作成し、print_values()
メソッドを呼び出しています。print_values()
メソッドは、__init__()
メソッドで初期化されたself.x
とself.y
の値を表示します。 結果は以下のようになります。
10
20
このように、__init__()
メソッドは、クラスのインスタンスが作成されるときに実行される初期化メソッドとして利用されます。
と、回答してくれる。さっと読むと、->は戻り値(出力)がある処理を作る場合に使う。 例えばaとbを足してcを出力するプログラムを作りたかったら、def(a,b) → c:と書けばいいんだな・・・ 今まで見たコードはみんな戻り値が無かったから、->が省略されていたのか・・・省略せずに->Noneと書く方法もあるんだな。と学ぶ。
ここで、ふとこのエラーになっている${0:pass}の行について訳が分からん。聞いてみよう。
Pythonのコードスニペットで__init__を定義しようとすると以下のように表示される。 def __init__ (self) -> None: ${0:pass} ここでいう${0:pass}について解説して欲しい。
${0:pass}
は、コードエディタや開発環境でコードスニペットを表すための特殊な記法です。この記法では、
$
と
{}
で囲まれた部分が変数やプレースホルダとして扱われます。 具体的に
${0:pass}
という記法について解説します。
${0:pass}
は、コードエディタや開発環境でコードスニペットを表すための特殊な記法です。この記法では、$
と{}
で囲まれた部分が変数やプレースホルダとして扱われます。 具体的に ${0:pass}
という記法について解説します。
${0}
: コードスニペットの変数番号を表します。この場合は最初の変数なので、番号は0です。この変数はテキストの入力位置を表し、コードスニペットを利用する際にカーソルが初期位置に置かれます。:pass
: 初期値またはデフォルト値を指定することができます。この場合は、初期値としてキーワードpass
(何もしない)が指定されています。 このコードスニペットを利用することで、__init__()
メソッドを定義しようとすると、カーソルが__init__
の後のpass
の位置に置かれます。これにより、__init__()
メソッドの中身を直接入力できるようになります。 例えば、以下のようなコードスニペットを利用することができます。
1def __init__(self) -> None:
2 ${0:pass}
このコードスニペットを利用すると、カーソル位置に pass
が表示されます。カーソルを移動して入力内容を修正することも可能です。 このように、コードスニペットを利用することで、既存のコードの一部を簡単に再利用したり、コードを迅速に書くことができます。
という記述から、良く分からんが消したらよかろうということが分かった。 バックグラウンドに知識として「コードスニペット」というのがスマホのテキスト入力である予測入力に近いものだという理解が要る。途中まで打つと、マッチする一式の文言をうち込んでくれる機能である。
予測変換と異なるのは、予め決めておいたルールに従って少し形を変えた状態で入力することができるようになっているところである。たぶん、コードスニペットを呼び出す際に、何か指定すると${0:pass}のところがうまい具合に置き換わるんだろう・・・ということにしておく。
こんどは__initi(self)__のselfは引数、つまり入力であると思われるが、これは何が入るんだろうか?変えていいんだろうか?変えるべきなんだろうか?消すべきか?などと疑問がわく。
実は1回目の回答にそれについて書いてあったのだけれど、再度聞いてみる。
ここでいうselfについて説明して。
__init__(self)
のself
は、クラスのインスタンス自体を参照するための特殊なパラメータです。このパラメータは、クラスのメソッドが呼び出されるときに自動的に渡されます。 self
は、通常、クラス内の他のメソッドやインスタンス変数にアクセスするために使用されます。self
を介して、クラス内の要素にアクセスすることができます。 self
は、クラスのインスタンスを参照するための慣習的な名前ですが、実際には必ずしもself
と命名する必要はありません。ただし、Pythonのプログラマの大半はself
を使用することが一般的です。 以下はself
を使用してインスタンス変数を定義する例です。
class MyClass:
def __init__(self, x):
self.x = x
def print_value(self):
print("x:", self.x)
この例では、self.x
というインスタンス変数を__init__()
メソッド内で定義しています。self.x
は、クラス内の他のメソッド(例えばprint_value()
メソッド)からもアクセスすることができます。 self
は、インスタンス自体を参照するためのパラメータであり、クラス内でのインスタンスの操作やデータの共有に重要な役割を果たします。
という具合に、嫌な顔一つせず再び答えてくれる。
なるほど。自分自身を参照するときにコレを使うのか・・・規格上は名前は好きに決めていいんだけれど、慣習的にみんなselfってつけてんだな・・・などなどが理解できる。
ただまあ、言い回しがちょっと複雑だから、自分の理解があっているのかちょっと心配である。Visual Basicだとこのような引数として与えられなくても、Meが自インスタンスとして使えるようになっていて、Me.x = xで通じる。
Pythonだとなんでselfとしてわざわざ書くのか疑問だ。VBのMeと同じ意味なのか?聞いてみる。
つまり、selfはVisualBasicでいうMeのようなもの?
はい、そのように考えることができます。
self
は、クラスのインスタンス自体を参照するためのパラメータです。Visual Basicの場合、
Me
を使用してインスタンス自体を参照します。
self
や
Me
は、クラス内でのインスタンスの操作やデータの共有に使用されます。例えば、インスタンス変数の参照や変更、他のメソッドの呼び出し、またはクラス内の他の要素へのアクセスに使用されます。 しかし、Pythonの
self
とVisual Basicの
Me
は、シンタックスや動作の面で異なる点もあります。Visual Basicの
Me
は、確実にインスタンス自体を参照しますが、Pythonの
self
は実際には慣習的な名前であり、別の名前でも問題ありません。また、Pythonでは
self
を省略することもできます(ただし、メソッド内でのインスタンス変数への操作が必要な場合は
self
を明示的に使用することが推奨されています)。 したがって、
self
と
Me
は同じ目的を持つものであり、クラスのインスタンス自体への参照を提供しますが、それぞれの言語の特定の構文や動作に従います。
ふーむなるほどね。 省略しても良いんだ。大抵のプログラムは省略して書いているんだな。
self以外に引数があるときはどうするの?
Pythonのクラスメソッドでは、self
以外にも引数を定義することができます。self
以外の引数は、そのメソッドが呼び出される際に渡す必要があります。 例えば、以下のようなクラスメソッドを考えてみましょう。
class MyClass:
def __init__(self, x):
self.x = x
def print_value(self, message):
print(message, self.x)
上記の例では、print_value()
メソッドにはself
とmessage
の2つの引数があります。self
はインスタンス自体を参照するためのパラメータであり、message
はメソッドに渡される任意のメッセージです。 インスタンスを作成し、print_value()
メソッドを呼び出す際には、self
以外の引数も渡す必要があります。
my_object = MyClass(10)
my_object.print_value("The value is:")
上記のコードでは、my_object
という名前のMyClass
のインスタンスを作成し、print_value()
メソッドを呼び出しています。print_value()
メソッドには"The value is:"
というメッセージが渡され、その後にself.x
(インスタンス変数x
の値)が表示されます。 結果は以下のようになります。
The value is: 10
このように、self
以外の引数をメソッドに定義することで、クラス内で必要な操作や計算を行うための入力を受け取ることができます。
selfは省略できると言っていたけれど、引数が一つの時、selfが省略されてself以外の引数が1つある場合と、selfが省略されず、self以外の引数が無い場合の違いってどう判断するの?
Pythonにおいて、クラスメソッドでself
以外の引数が1つある場合と、self
が省略されてself
以外の引数がない場合の違いを判断するには、次のようなポイントを考慮する必要があります。
- メソッドがインスタンスメソッドであるかクラスメソッドであるかを確認する必要があります。通常、インスタンスメソッドでは
self
が第一引数として渡され、クラスメソッドではself
以外の第一引数が利用されます。クラスメソッドとして定義されている場合は、self
が省略されてself
以外の引数がないことを意味します。 - コードの文脈を考慮する必要があります。
self
が省略されている場合、そのメソッドがクラス内の静的メソッド、クラスメソッド、あるいは関数として定義されている可能性があります。具体的な実装の詳細や意図を確認する必要があります。 例えば、次のようなコードを考えてみましょう。
class MyClass:
def method_with_arg(arg):
print(arg)
@classmethod
def class_method(cls, arg):
print(arg)
@staticmethod
def static_method():
print("Static Method")
この例では、method_with_arg()はselfが省略されており、argという1つの引数があります。これはクラス内の静的メソッドまたは関数として定義されている可能性があります。 一方、class_method()とstatic_method()は、クラスメソッドおよび静的メソッドとしてデコレートされているため、selfが省略されていません。 実際のコードでselfが省略されてself以外の引数が1つある場合と、selfが省略されず、self以外の引数がない場合の違いを判断するには、上記の要素を考慮しながらコードを分析する必要があります。
なるほど。コードを見ないとわからないのね。
はい、正確な判断をするにはコードを見る必要があります。コードの文脈やメソッドがどのように使用されているかを把握することで、
self
の有無や引数の有無が明確になります。
self
の有無や引数の有無は、クラス内のメソッドがどのような目的を持ち、どのように使われているかに基づいて決まります。そのため、単純にルールを当てはめるだけでなく、コードの意図を理解することが重要です。 また、他のプログラマとのコミュニケーションやチーム開発の場では、コードの可読性を高めるためにコメントやドキュメンテーションを活用することも重要です。例えば、メソッドのドキュメンテーション文字列やコメントによって、メソッドの目的や引数の意味を明確にすることができます。これにより、コードを読みやすくし、他の開発者がメソッドの動作や利用方法を理解しやすくすることができます。
という具合に、なんというんだろう、詳しい人に対話しながら聞くみたいなことができる。 AIは間違った回答を返す場合もあるから、重要度に応じて裏取りをしないといけないけれど、それは人に聞く場合も一緒。
ある意味「個別家庭教師」みたいなことができると思う。
英語や数学といった一般的な学問についても、こんな風に「理解を妨げているポイントについて質問して、その帰ってきた答えで理解を深める」みたいなことができる。
学習の場においてAIを使うというと、「答えにひとっ飛びして人間が馬鹿になる」と言われがちだが、そうじゃない使い方もできる。というわけだ。