x の浅い (shallow) コピーを返します。
「どうやって」がありません。つまり本当のところ仕様が書かれてません。
クラス独自のコピー実装を定義するために、特殊メソッド
__copy__()
および__deepcopy__()
を定義することができます。
じゃぁ、リストにはこのメソッドがあるのでしょうか。
>>> lst = [1, 2, 3]
>>> lst.__copy__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__copy__'
ないじゃん。
以下は Python 3.6.1 での copy.copy()
の実装です。
def copy(x):
"""Shallow copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
cls = type(x)
copier = _copy_dispatch.get(cls)
if copier:
return copier(x)
try:
issc = issubclass(cls, type)
except TypeError: # cls is not a class
issc = False
if issc:
# treat it as a regular class:
return _copy_immutable(x)
copier = getattr(cls, "__copy__", None)
if copier:
return copier(x)
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error("un(shallow)copyable object of type %s" % cls)
if isinstance(rv, str):
return x
return _reconstruct(x, None, *rv)
_copy_dispatch = d = {}
def _copy_immutable(x):
return x
for t in (type(None), int, float, bool, complex, str, tuple,
bytes, frozenset, type, range, slice,
types.BuiltinFunctionType, type(Ellipsis), type(NotImplemented),
types.FunctionType, weakref.ref):
d[t] = _copy_immutable
t = getattr(types, "CodeType", None)
if t is not None:
d[t] = _copy_immutable
d[list] = list.copy
d[dict] = dict.copy
d[set] = set.copy
d[bytearray] = bytearray.copy
...
copy.copy()
は組み込みデータ型においてはそれぞれ浅いコピー (と深いコピー) を実現する関数を予め辞書で保持しており、その辞書に登録されていない場合には __copy__()
メソッドを探します。
それ以降は pickle
モジュール絡みの規約に基づいた振る舞いをするようですが本稿の想定を越えてるので省略。ドキュメントの以下の部分に相当します。
クラスは、コピーを制御するために pickle の制御に使用するのと同じインターフェースを使用することができます。これらのメソッドについての情報はモジュール pickle の説明を参照してください。実際、 copy モジュールは、 copyreg モジュールによって登録された picle 関数を使用します。
その点は置いておくとして、ソースコードにより、copy.copy(lst)
は lst.copy()
と等価と考えられます。
ちなみに Python 2系には list.copy()
というものはなく、 lst[:]
で代用します。古いドキュメントで2から3に移行したものだと lst[:]
を相対的に良く見かけるかもしれません。