72012


やりたいことはベーシック認証を突破してあるHPからデータをダウンロードする事です。  
この後 URL,保存するファイルのパスを指定を指定していきます。  
教わったプログラムは下記のプログラムを含みます。

`format`関数だと、`'任意の文字列{}任意の文字列'.format(変数)`と記載をすると思っています。  
`{}`の間の`:`がどういう意味を持つのか、`format`関数の`,`がどういう意味を持つのか、なぜここに入れればできるのかを教えていただけませんでしょうか。

[code]

    import urllib.request 
    import base64 
     
    user = 'abcde'
    password = '12345'
    basic_user_and_pasword = base64.b64encode('{}:{}'.format(user, password).encode('utf-8'))
    
[/code]


CC BY-SA 4.0
2020-11-17T13:11:22.013
72011
2020-11-27T11:36:54.957
2020-11-17T13:18:05.343
32986
31472
question
python python3 base64
base64.b64encodeの構文の中身


> `format`関数だと、`'任意の文字列{}任意の文字列'.format(変数)`と記載をすると思っています。

その記述でどこまでご理解されているのか掴みかねるのですが、

[code]

    '任意の文字列1{}任意の文字列2{}任意の文字列3'.format(式1,式2)
    
[/code]

と言うのも正しい[`format`メソッド](https://docs.python.org/3.4/library/string.html)の使い方であり、`式1`の値が1つ目の`{}`に、`式2`の値が2つ目の`{}`に埋め込まれる形になります。

ここで`任意の文字列1`と`任意の文字列3`を空、`任意の文字列2`を`:`に置き換えてやると、ご質問にある、

[code]

    '{}:{}'.format(user, password)
    
[/code]

と言う式が出来上がります。

つまり、1つ目の`{}`を`user`の値で、2つ目の`{}`を`password`で置き換えた文字列を作れ、と言う意味ですね。

その部分を

[code]

    (user + ':' + password)
    
[/code]

と書いても全く同じ結果になります。

この場合の`:`には特別の意味はなく、単に結果にそのまま埋め込めたい「任意の文字列」でしかありません。


CC BY-SA 4.0
2020-11-17T13:35:31.993
72012
2020-11-17T13:35:31.993
13972
72011
answer


format関数の具体的な用例をいくつか示します。

[code]

    print('{}'.format(user))
    -> abcde
    
[/code]

[code]

    print('user: {}'.format(user))
    -> user: abcde
    
[/code]

つまりformat関数には、文字列中の `{}`を、format関数の引数に置き換える機能を持っています。

> `{}`の間の`:`がどういう意味を持つのか

format関数が影響を及ぼすのは`{}`のみであるため、`:`は何にも影響しません。  
…が、本来の目的のbasic認証とは大いに関係があります。  
basic認証が設定されているページは、ブラウザのポップアップに入力する手段の他に、URLに直接記述を行うことでも認証を突破することができます。  
例) http://user:password@www.hoge.com/  
この例のようにユーザ名とパスワードを `:`で区切る必要があるため、`{}:{}`という書き方になっていると思われます。  
(おそらく、プログラムの後半に
`'https://{}@www.hoge.com'.format(basic_user_and_pasword)`のような記述があるのではないでしょうか？)

> format関数の`,`がどういう意味を持つのか

format関数が文字列中の `{}` を変数に置き換えることができるのは、ひとつだけではありません。  
format関数の引数に `,`を使うことでいくつも要素を追加することで、複数の `{}`を置き換えることができます。  
つまり`,`とは、要素の区切りのことです。

たとえば

[code]

    print('{}{}'.format('hello ', 'world!'))
    -> hello world!
    
[/code]

また、複数個の場合は前から順番の置き換えになります。

[code]

    print('{}{}{}{}'.format('A', 'B', 'C', 'D'))
    -> ABCD
    
[/code]

発展させて、以下のようにも書くことができます。

[code]

    print('I have a {}, I have an {}.'.format('pen', 'apple'))
    -> I have a pen, I have an apple.
    
[/code]

ちなみに`{}`の数とformat関数の引数が同数でないときは、以下のようになります。

format関数の引数の方が多い場合

[code]

    print('{}{}{}{}'.format('A', 'B', 'C', 'D', 'E'))
    -> ABCD  # 最後の'E'は無視される
    
[/code]

`{}`のほうが多い場合

[code]

    print('{}{}{}{}'.format('A', 'B', 'C'))
    -> Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: tuple index out of range  # 引数が足りないというエラーになる
    
[/code]

以上のことを踏まえると、`{}:{}`は以下のような出力になることがわかります。

[code]

    user = 'abcde'
    password = '12345'
    print('{}:{}'.format(user, password))
    -> abcde:12345
    
[/code]

* * *

蛇足ですが、すこし冗長ながら以下のように記述することもできます。

[code]

    user = 'abcde'
    password = '12345'
    
    # 以下の3行が↓とおなじ
    # basic_user_and_pasword = base64.b64encode('{}:{}'.format(user, password).encode('utf-8'))
    user_and_password = '{}:{}'.format(user, password)
    user_and_password_encoded = user_and_password.encode('utf-8')
    user_and_password_b64 = base64.b64encode(user_and_password_encoded)
    
[/code]


CC BY-SA 4.0
2020-11-27T11:36:54.957
72241
2020-11-27T11:36:54.957
42796
72011
answer