frame
とobject
は、それらが意味するとは限りません。
プログラミングでは、スタックと呼ばれるものがあります。 Pythonでは、関数を呼び出すと、スタックフレームという名前のものが作成されます。このフレームは、基本的には、関数のローカルなすべての変数のテーブルです(例のように)。
関数を定義すると、という関数が新しいスタックフレームを作成しません。という関数が呼び出されます。例えば、このような何か:say_hello
:
def say_hello():
name = input('What is your name?')
print('Hello, {}'.format(name))
あなたのグローバルフレームは、ただ一つの参照を保持しようとしています。
print(locals())
をあなたはこのようなものが表示されます:あなたは(:名前空間の間の1の関係、範囲、およびフレームスタックPythonであなたはほとんどが1を持っている)ローカル名前空間に何があるかチェックアウトしていることがわかります:名前(ダブルアンダースコア2つのアンダースコアのために短い)
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1019bb320>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/private/tmp/fun.py', '__cached__': None, 'say_hello': <function say_hello at 0x101962d90>}
注dunder - これらは自動的に提供され、そして私たちの議論の目的のために、あなたはそれらを無視することができます。それでは、私たちは次のようになります。
{'say_hello': <function say_hello at 0x101962d90>}
その0x
ビットは、関数自体が存在するメモリアドレスです。そこでここでは、グローバルスタック/フレームにはその値が1つだけ含まれています。関数を呼び出してlocals()
を再度チェックすると、name
は存在しないことがわかります。これは、関数を呼び出すときに新しいスタックフレームを作成し、そこに変数が割り当てられるからです。これは、関数の最後にprint(locals())
を追加することで証明できます。次に、次のようなものが表示されます:
{'name': 'Arthur, King of the Brits'}
ここではダンダーの名前はありません。また、メモリアドレスは表示されません。この価値がどこにあるのかを知りたい場合は、そのための機能があります。それはフレームについて話したときの例では、何を意味するのかだ
def say_hello():
name = input('What is your name?')
print('hello {}'.format(name))
print(locals())
print(id(name))
return name
print(id(say_hello()))
。
しかし、オブジェクトについてはどうですか?まあ、Pythonでは、すべてはオブジェクトです。ちょうどそれを試してみてください。
>>> isinstance(3, object)
True
>>> isinstance(None, object)
True
>>> isinstance('hello', object)
True
>>> isinstance(13.2, object)
True
>>> isinstance(3j, object)
True
>>> def fun():
... print('hello')
...
>>> isinstance(fun, object)
True
>>> class Cool: pass
...
>>> isinstance(Cool, object)
True
>>> isinstance(Cool(), object)
True
>>> isinstance(object, object)
True
>>> isinstance(isinstance, object)
True
>>> isinstance(True, object)
True
彼らはすべてオブジェクトです。しかし、それらは異なるオブジェクトかもしれません。あなたはどうやって話すことができますか? id
で:
>>> id(3)
4297619904
>>> id(None)
4297303920
>>> id('hello')
4325843048
>>> id('hello')
4325843048
>>> id(13.2)
4322300216
>>> id(3j)
4325518960
>>> id(13.2)
4322300216
>>> id(fun)
4322635152
>>> id(isinstance)
4298988640
>>> id(True)
4297228640
>>> id(False)
4297228608
>>> id(None)
4297303920
>>> id(Cool)
4302561896
あなたはまた、二つのオブジェクトかどうかを比較することができます注is
を使用して同じオブジェクトです。
>>> True is False
False
>>> True is True
True
>>> 'hello world' is 'hello world'
True
>>> 'hello world' is ('hello ' + 'world')
False
>>> 512 is (500+12)
False
>>> 23 is (20+3)
True
Ehhhhh ...?ちょっと待って、何が起こったの?さて、それが判明したように、python
(すなわち、CPython)caches small integers。したがって、オブジェクト512
は、オブジェクト12
に追加されたオブジェクト500
の結果であるオブジェクトとは異なります。注意すべき
一つ重要なことは、代入演算子=
常にが同じオブジェクトに新しい名前を割り当てることです。たとえば、次のように
>>> x = 592
>>> y = 592
>>> x is y
False
>>> x == y
True
>>> x = y
>>> x is y
True
>>> x == y
True
そして、あなたがオブジェクトを与える、またはあなたがobject around to different framesを渡す場合でも、あなたはまだ、同じオブジェクトを持っているどのように多くの他の名前は重要ではありません。
しかし、あなたが収集するために開始しているとして、それは変更新しいオブジェクトを生成したオブジェクトと操作される操作の違いを理解することが重要です。一般的には、Pythonでfew immutable typesがあり、それらの操作によって新しいオブジェクトが生成されます。
あなたの質問については、いつオブジェクトを変更したいのですか?いつそれらを同じにしておきたいのですか?実際には間違った方法で見ています。変更が必要な場合は変更可能な型を使用し、変更したくない場合は変更不可能な型を使用します。
たとえば、グループがあり、グループにメンバーを追加したいとします。リストのような変更可能な型を使用してグループを追跡したり、メンバを表す文字列のような不変型を使用することができます。このように:
>>> group = []
>>> id(group)
4325836488
>>> group.append('Sir Lancelot')
>>> group.append('Sir Gallahad')
>>> group.append('Sir Robin')
>>> group.append("Robin's Minstrels")
>>> group.append('King Arthur')
>>> group
['Sir Lancelot', 'Sir Gallahad', 'Sir Robin', "Robin's Minstrels", 'King Arthur']
グループのメンバーが食べられるとどうなりますか?
>>> del group[-2] # And there was much rejoicing
>>> id(group)
4325836488
>>> group
['Sir Lancelot', 'Sir Gallahad', 'Sir Robin', 'King Arthur']
メンバーが変更されているにもかかわらず、同じグループがまだ存在することがわかります。
呼び出しスタックについて話している場合、[フレーム](https://en.wikipedia.org/wiki/Call_stack#STACK-FRAME)は、ローカルに作成されたすべてのオブジェクトを含むものです即時の範囲。あなたのスクリーンショットでは、青いボックス全体が1つのフレームであり、 'l1'、' l2'、および 'item'という名前に関連付けられたオブジェクトを含んでいます。フレームを直接制御することはできません。オブジェクトとその名前だけを制御できます。 – Kevin