0

tl;dr: オプションの引数の型をカスタム ビルド クラスに設定する方法を知りたいです。

コード:

class Point(object):
    def __init__(self,x=int,y=int):   # Initialize Point object with optional args
        self.val=(x,y)
    def __add__(self,p=Point):        # p=Point is the issue
        ...

私はもう試した:

def __add__(self,p=self.__class__):  # Cannot reference self in an arg.
def __add__(self,p=Point):           # Point is not defined

長い話:

私はこれまでに何も見つけられなかったいくつかの検索を行いましたが、私が使用している用語の方が多いと思います.

私は 2 次元の Point/Vector クラスを作成しています (わかっていますが、既に完了していますが、自分の書き方を学び、開発しています)。ほとんどの場合、主にメンテナンスの容易さ。

オプションの引数の型を、Python の組み込み型の 1 つではなく、上記の Point などのカスタム ビルド クラスに設定する方法を理解できませんでした。

注:単純にpa位置引数を作成するだけで機能することは承知していますが、そうしない主な理由がない限り、pythonの哲学に対して少し厳格であることを除いて、私はしたいと思いますコードをわかりやすくするために引数を入力します。

それはどのように達成できますか、それは価値がありますか、そしてこの方法で物事を行うことの短所はありますか?

この種のベスト プラクティスに関するヒントも大歓迎です。

4

3 に答える 3

2

ガブリエルの答えは正しいです。これはおそらくあなたが望むものではありません。

しかし、あなたが見ている実際の症状に関しては、組み込み型とカスタム型とは何の関係もありません。問題は、関数が定義されるとすぐにデフォルト引数が評価されることですが、クラス本体が終了するまでクラスは存在しません。そのため、実行中のその時点ではまだ存在しないPointため、独自のクラス本体内でデフォルト引数として使用することはできません!Point

于 2014-07-23T07:35:01.677 に答える
2

x=intコードで何をしているのかを誤解している可能性があると思いますy=int

class Point(object):
    def __init__(self,x=int,y=int):   # Initialize Point object with optional args
    ...
    def __add__(self,p=Point):  

のインスタンスのPoint作成

u = Point()

はオブジェクトを生成しますu。オプションの引数xyは、非整数を表す Python オブジェクトと等しくなりint typeます (ここでは、1、3、99 などの整数とその type=int を区別します)。一般に、関数の引数で等号を使用すると、型ではなくデフォルト値が指定されます。同様に、引数が関数にp渡されない場合、クラスを表すオブジェクトと等しくなります。クラスのインスタンスは作成されません。関数の引数の型を事前に指定することはできません。さらに、それらのタイプは関数内で変更できます。これは、Python が動的型付け言語であるためです。 addpPointpPoint

ダックタイピングに関するこのページは、物事を明確にするのに役立つかもしれません。必要に応じて、引数が渡された後に引数の型を確認し、その情報に基づいて操作することもできますが、基本的な考え方は、引数が のように歩き、 のようintに話すint場合、実際の型が であるかどうかは関係ありませんint

ダック タイピングの記事の Python セクションでは、Python の例外の説明と、これらの状況での推奨される使用法について説明しています。

于 2014-07-23T07:19:59.757 に答える
1

私があなただったら、これを行うためにタプルをサブクラス化します。

>>> class Point(tuple):
...     def __new__ (cls, x, y):
...         return super(Point, cls).__new__(cls, (x,y))
...     def __init__(self, x, y):
...         super(Point, self).__init__(x,y)
...         self.x=int(x)
...         self.y=int(y)
...     def __add__(self,point_add):
...         if len(point_add) != 2:
...             exit("Not a coordinate")
...         new_x = self.x + int(point_add[0])
...         new_y = self.y + int(point_add[1])
...         new_point = self.__new__(Point, new_x, new_y)
...         new_point.x = new_x
...         new_point.y = new_y
...         return new_point
... 
>>> p_a = Point(1, 2)
>>> p_b = Point(1, 2)
>>> p_c = p_a + p_b
>>> print "tuple:", p_c
tuple: (2, 4)
>>> print "x:", p_c.x, "y:", p_c.y
x: 2 y: 4
>>> 

これにより、ポイントをタプルとして扱い、ある程度タプルをポイントとして扱うことができます。上記の__add__()方法は、タプルまたはポイントのいずれかを追加するために機能します。

于 2014-07-23T07:47:32.987 に答える