2016-03-27 8 views
0

私は、誰かに、コード内でよく使われる定数を変数に置き換えるよう教えてくれました。たとえば、次のように定数はPythonの変数よりも多くのメモリを占有しますか?

if a > 50: 

のようなもので:数50は、一般的に私のコード(このような比較のために例えば)を中心に使用されているという事実を考慮し

b = 50 
if a > b: 

。それでは、実際にはどうなっていますか?この目的のための変数はよりメモリにやさしいか、コーディングスタイルのためだけですか?私はPython 3.4を使用しています

+3

小さなintはcpythonにキャッシュされますので、あまりにも多くの時間を費やすことなく、同じものを使用してください。 –

+2

読みやすいものを使用してください。メモリはここでは問題ではありません。 –

+2

あなたのコードでは50が "よく使われる定数"であると言われています。その場合は、50を変数として格納し、おそらくは「b」よりも読みやすい名前で格納する方が優れたコーディングスタイルであり、変数を使用します。 – Hun

答えて

6

中心的な場所に設定されている変数を定数に置き換えるの背後にある考え方は、アプリケーション管理についてのメモリ管理についての少ないが、よりです。定数は一定であると考えられますが、アプリケーションの要件を変更すると、これらの定数の値を調整する必要が頻繁にあります。

したがって、a > 50のチェックがある場合、将来的にはa > 60を確認する必要があります。その場合、新しい要件を反映するためにコードを更新する必要があります。

定数のアイデアは、あなたが唯一の中心的な場所でこれらの数字を調整しなければならないこと、今です。たとえば、constants.pyモジュールを使用して重要な定数をすべて中央の場所に宣言し、チェックを実行するのはa > constants.SOME_THRESHOLDのみです。その場合、要件が変更された場合、その定数が使用されているすべての場所を検索するのではなく、単一の場所で定数値を変更するだけです。

あなたが同じ値を持っていますが、異なるものを意味する別の定数を持っている場合、これは、さらに重要です。たとえば、チェックには2つの異なる定数が使用されており、両方の値は50の値から始まります。これらの定数の1つについては、値を60に変更する必要があります。コード内の実際の値を使用して、50が発生するたびに、60であるか、50であるかを判断する必要があります。しかし、集中定数では、定数を更新するだけですべてが正しく動作します。一定の変数を持つ

はまた、あなたこれらの定数は、実際の名前を取得するという利点を提供します。 50は何でも意味することができます。変数名があれば、それが意味するものを説明する名前を付けることができます。

もちろん、このような集中定数を持つことは、すべてにとって意味がありません。一定の値が一定の変数として抽出されるのが適切であり、そうでない場合があります。

は限りメモリが行くように、いくつかの点で変数を宣言もちろん変数がどこかに保存することが必要です。しかし、変数は非常に安いので、それは本当に問題ではありません。とにかくこの値はリサイクルされる可能性が高いでしょう。小さい整数の場合、Pythonは実際の定数オブジェクトをキャッシュとして予約します。

+0

投稿、@ポーク – n1c9

+0

事は、変数は定数ではありません。したがって、Python 3.4以降では 'enum'を使う方がいいでしょう。 –

+0

通常の方法は、定数を表現する変数を 'ALL_UPPERCASE'に書くことです。そうすれば、それらに書き込むべきではないことは明らかです。 – poke

1

一般的に、マジックナンバーは悪いスタイルと見なされます。あなたのコードを読んでいるとき、 "50"が何を意味するのかははっきりしないかもしれません。分?ドル?そういうわけで、あなたはMAX_MINUTES = 50のようなことをします。誰かがそこで起こっていることを理解するのに非常に役立つコードに応じて。

0

あなたは、Python 3.4を使用しているので、私はIntEnumで、すべてのマジックナンバーを交換することをお勧め。

これにより、コードをわかりやすくし、必要に応じて変更しやすくなります。

enumを使用する利点は、変数の場合と同じように、値を誤って変更できないことです。

このコードを検討してください。

import os 
from hashlib import sha256 

def compare(src, dest): 
    """ 
    Compare two files. 

    Arguments 
     src: Path of the source file. 
     dest: Path of the destination file. 

    Returns: 
     0 if source and destination are different 
     1 source and destination are identical 
     2 destination doesn't exist 
     3 source doesn't exist 
    """ 
    xsrc, xdest = os.path.exists(src), os.path.exists(dest) 
    if not xsrc: 
     return 3 
    if not xdest: 
     return 2 
    with open(src, 'rb') as s: 
     csrc = sha256(s.read()).digest() 
    if xdest: 
     with open(dest, 'rb') as d: 
      cdest = sha256(d.read()).digest() 
    else: 
     cdest = b'' 
    if csrc == cdest: 
     return 1 
    return 2 

このコード自体は不明ではありません。それはすべて文書化されています。 しかし、一度を試して返信値をにすると、常にドキュメントを参照する必要があります。

以下のコードは、その動作をなぜ説明しますか? compareのドキュメントを参照しているわけではありません。

res = compare(file_a, file_b) 
if res == 1 or res == 3: 
    pass 
elif res == 0: 
    # copy file_a to file_b 

これを見てください。

import os 
from hashlib import sha256 
from enum import IntEnum 

class Cmp(IntEnum): 
    differ = 0 # source and destination are different 
    same = 1 # source and destination are identical 
    nodest = 2 # destination doesn't exist 
    nosrc = 3 # source doesn't exist 

def compare(src, dest): 
    """ 
    Compare two files. 

    Arguments 
     src: Path of the source file. 
     dest: Path of the destination file. 

    Returns: 
     Cmp enum 
    """ 
    xsrc, xdest = os.path.exists(src), os.path.exists(dest) 
    if not xsrc: 
     return Cmp.nosrc 
    if not xdest: 
     return Cmp.nodest 
    with open(src, 'rb') as s: 
     csrc = sha256(s.read()).digest() 
    if xdest: 
     with open(dest, 'rb') as d: 
      cdest = sha256(d.read()).digest() 
    else: 
     cdest = b'' 
    if csrc == cdest: 
     return Cmp.same 
    return Cmp.differ 

これを使用すると、次のようになります。

res = compare(file_a, file_b) 
if res == Cmp.same or res == Cmp.nosrc: 
    pass 
elif res == Cmp.differ: 
    # copy file_a to file_b 

これは、compareのドキュメントを参照しなくてもわかります。おそらく、Cmp列挙型の詳細を確認する必要はありません。

関連する問題