4

から継承するクラスがあるプログラムを書いていましたtuple。ただし、引数をリストとして渡しても機能しました。これが私のコードの一部です:

class Board(tuple):    
    def __init__(self, tup):
        print(type(tup))
        super().__init__()

board = Board([[Cell(False) for i in range(10)] for j in range(10)])
print(type(board))

次に、このプログラムは次を出力します。

<class 'list'>
<class '__main__.Board'>

私の質問は次のとおりです。私が alistを渡すと言ったときに、Python が引数としてa を渡させたのはなぜtupleですか?

4

6 に答える 6

5
def __init__(self, tup):

他の機能と同じです。tupそして、パラメーターのリストを渡しました。Python でパラメータの型を制限する方法はありません。サブクラス化tupleとは、 からプロパティを継承していることを意味するだけでありtuple、タプルのみをパラメーターとして受け入れることができるという意味ではありません。

編集:何らかの理由で、タプルのみが受け入れられるようにする方法がどうしても必要な場合。このような例外を発生させることができます

class Board(tuple):
    def __init__(self, tup):
        if not isinstance(tup, tuple):
            raise TypeError("Constrcutor argument to Board should be a tuple")
        super().__init__()

print Board([1, 2])

出力

TypeError: Constrcutor argument to Board should be a tuple

tupleとの性能比較list

class Board(tuple):
    def __init__(self, tup):
        for i in tup:
            pass
myList, myTuple = range(10), tuple(xrange(10))

from timeit import timeit
print timeit("Board(myList)", "from __main__ import myList, Board", number = 1000000)
print timeit("Board(myTuple)", "from __main__ import myTuple, Board", number = 1000000)

出力

0.44806599617
0.413192987442

これは明らかに、lista をパラメーターとして渡すことが、よりわずかに遅くtuple、ほとんど無視できることを示しており、パフォーマンスはほぼ同じです。

于 2013-10-28T14:28:57.123 に答える
1

tupタプルであることを期待しているとはどこにも言いませんでした。明示的にリストを渡しましたが、Python の引数は型チェックされていません。次のように引数の型を制限できます。

if type(tup) is not type(()):
    raise ValueError('Expected a tuple')

ただし、これは実際には必要ありません。このようなことを行うPython的な方法は、持っているオブジェクトのタイプを気にするのではなく、実行したい操作をサポートしているかどうかを気にすることです.

于 2013-10-28T14:27:47.753 に答える
1

tuple、イニシャライザに渡される引数の内容ではなく、ボード自体の内容を記述します。

初期化子への引数は、必ずしもオブジェクト自体を表すとは限りません。それらは、新しいオブジェクトのパラメーターのようなものになる可能性があります。関数が実際には入力に対して何もしない場合、文字通り何でも渡すことができます。

于 2013-10-28T14:28:17.207 に答える
0

リストとタプルはどちらも、シーケンスとして同じ意味で使用されることがよくあります。

リストとタプルの違いは、ハッシュとして使用しようとする場合に重要になります。

class Board(tuple):    
    def __init__(self, tup):
        print(type(tup))
        d={}
        d[tup]='test'          # this will fail with an unhashable type, like a list
        super().__init__()

b1=Board(tuple([1,2,3]))
b2=Board([1,2,3])

版画:

<class 'tuple'>
<class 'list'>
Traceback (most recent call last):
  File "Untitled 8.py", line 9, in <module>
    b2=Board([1,2,3])
  File "Untitled 8.py", line 5, in __init__
    d[tup]='test'
TypeError: unhashable type: 'list'

通常、Python には型チェックはありません。EAFP言語です 。

より「正式な」区別と型のサブクラス化の正式なチェックが必要な場合は、基本型の代わりにcollections.abcを使用することを検討してください。

于 2013-10-28T14:30:26.893 に答える
-1

あなたのコードは本質的にこれを行います。

>>> tuple([1,2,3])  # tuple() takes a list
(1, 2, 3)           # turns it into a tuple

からサブクラス化しtupleても、クラスの引数は に制限されませんtupletupleインスタンスと同じメソッドが含まれているだけです。

于 2013-10-28T14:28:57.070 に答える