2017-09-08 5 views
2

鋳造:パイソン型変換/ Iは、次の2つのコードスニペットの差があるか疑問だ構文の違い

float_var = 1234.5678 
a = int(float_var) 
b = (int)(float_var) 

両者が正常、少なくともパイソン3.6(整数Iに変数を変換しますこの動作が2.7でサポートされているかどうかはわかりませんが)構文には明らかな違いがあります。さらに、次のスニペットは失敗します。私をリード

c = (int)float_var 

は、変数名(それがされるように、またはリテラル)は括弧で囲まなければならないことを信じるように。

私が2つの例の違いを集めることができるのは、最初のものがパラメータを__init__メソッドに渡すことによってクラスの新しいインスタンスを作成することです。 2番目の例では、intオブジェクトはメソッド__float__を定義するので、floatをintのインスタンスに「キャスト」することができます。

これは正しいと思いますか?また、なぜ3番目の例が失敗するのでしょうか?私はなぜかっこが "キャスト"されている値を囲む必要があるのか​​分かりません。

+0

また、2番目の例が最初の例ほど広く使用されていない理由はありますか?私の推測では、それは明らかではないが、わからない。 –

+0

「a」と「b」は同一です。 – Blender

+0

'int'のまわりの括弧は単純に何もしません。あなたは 'dis'モジュールを使って結果のバイトコードを見ることができます。 –

答えて

5

違いはありません。

Python型はオブジェクトであり、関数と同様に呼び出すことができます。 int(foo)の構文はPythonとCによって共有されるかもしれませんが、類似点はそこで終わりです。

コードでは、int == (int) == ((int))はすべて同じ方法で同じです1 + 1 == (1 + 1) == ((1 + 1))。あなたはバイトコードを見れば、Pythonは両方とも同じように扱います:

In [42]: dis.dis(lambda: (int)(a)) 
    1   0 LOAD_GLOBAL    0 (int) 
       3 LOAD_GLOBAL    1 (a) 
       6 CALL_FUNCTION   1 
       9 RETURN_VALUE 

In [43]: dis.dis(lambda: int(a)) 
    1   0 LOAD_GLOBAL    0 (int) 
       3 LOAD_GLOBAL    1 (a) 
       6 CALL_FUNCTION   1 
       9 RETURN_VALUE 

3番目の例は、PythonはCではないので、それが有効なPythonコードではありませんので、あなたがSyntaxErrorを取得できません。

2

aとbには違いはありません。彼らが違うと言うのは、2(2)が違うということです。関数を括弧なしで呼び出すことができないため、3番目の例は失敗します。たとえば、パラメータを囲む括弧がないため、int 5は機能しません。

5

私はこれを正しく考えていますか?

いいえかっこで捨てています。 2つの方法は同等です。この:

(int)(float_var) 

はこれと同じです:

int(float_var) 

それはいくつかの特別な "鋳造" 構文ではありません。それはちょうど名前の周りのかっこです。 The Python grammar allows this

>>> import ast 
>>> ast.dump(ast.parse('(int)(float_var)')) 
"Module(body=[Expr(value=Call(func=Name(id='int', ctx=Load()), args=[Name(id='float_var', ctx=Load())], keywords=[]))])" 
>>> ast.dump(ast.parse('int(float_var)')) 
"Module(body=[Expr(value=Call(func=Name(id='int', ctx=Load()), args=[Name(id='float_var', ctx=Load())], keywords=[]))])" 

しかし、第三の方法は、Python文法によって許可されていない。

atom: ('(' [yield_expr|testlist_comp] ')' | 
     '[' [testlist_comp] ']' | 
     '{' [dictorsetmaker] '}' | 
     NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') 
testlist_comp: (test|star_expr) (comp_for | (',' (test|star_expr))* [',']) 
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME 

パーサーは、各メソッドに対する等価抽象構文木を返します。上記のように、名前の周りの括弧は特別なものではありません。いずれかの方法で関数呼び出しに変換されます。したがって、intの前後の括弧は省略可能ですが、最後の括弧は省略されています。

関連する問題