3

言語で多くの異なるデータ型を使用する利点は何ですか?私は最近pyqtとpyqwtを使用していますが、次のような行を入力し続けています。

grid.setPen(Qt.QPen(Qt.Qt.gray, 0, Qt.Qt.DotLine))
curve.setSymbol(Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse,
                              Qt.QBrush(),
                              Qt.QPen(Qt.Qt.black),
                              Qt.QSize(5, 5)))

上記の行が代わりに次の場合、何が失われますか?:

grid.setPen('gray', 0 ,'dotted')
curve.setSymbol('ellipse', 'k', (5,5))

技術的な理由で特定のタイプが必要な場合でも、それらを必要とするメソッド内で文字列をそれらのタイプに変換できませんでしたか?

これは、pyqtとpyqwtが単にC ++ライブラリのバインディングであるためですか?もしそうなら、なぜそれらはC ++で必要ですか?

4

5 に答える 5

4

There are a few benefits:

  1. Type safe languages (like C++) have the advantage that many errors are found at compile time (as opposed to run-time). That means using Qt.grey (note the e) would fail to compile because the type is not defined.

  2. Better performance and less memory. Behind the scenes Qt.gray is a number, and number operations are much faster than strings.

In the pyqt case, because the library wraps a C++ library it looks more like c++ than like Python code.

于 2011-12-31T09:06:45.193 に答える
3

Different types let you check at compile time (at least, in C++) that you're passing the right kinds of things - for instance, if everything took strings, it'd be very easy to accidentally typo 'gray' as, say, 'grey', and possibly confuse the library.

A normal pattern is to do something more like this:

greypen = Qt.QPen(Qt.Qt.gray, 0, Qt.Qt.DotLine)
blackpen = Qt.QPen(Qt.Qt.black, 0, Qt.Qt.DotLine)
# ...
grid.setPen(greypen)
# ...
grid.setPen(blackpen)

That way you don't wind up repeating yourself if you're using the same kinds of attributes multiple times.

于 2011-12-31T09:04:40.823 に答える
1

It's because they are objects if you use this QPen::QPen () then what it does is Construct a default black solid line pen with 0 width. but since it's overloaded you can use parameters for those constructors when you pass a parameter in the QPen class what you send is processed and the result would return. so those are concepts of object orientations. you need to make an instance and that instance will handle the underlying part of it. if you use a string parameter like what you've used in the second example it will just use string type instead Qt.QPen() type. setPen() function asks for an object typed QPen() not string typed variable. the advantage is you don't need to write everything from ground floor. and some parts are predefined like a video game. in video game you can't do a lot of functions. if you shoot at someone he will shoot you or run away so the reaction is depend on the action you make. the action is the parameter and reaction is the return value from one of functions in that class. behind the scene there might a ton of codes which do various tasks. like how he reacts, the timing, whether he runs or walk or fly when you shoot so those are set at default value unless you change them specially. sometimes you don't need to change those default values or it would take time.in that case just pass the action and get the reaction. that's what this does. it's really useful for complex programs.

于 2011-12-31T09:05:42.493 に答える
1

Imagine that you make a typo, or a spelling mistake. So for example you write Elipse instead of Ellipse.

If you code with Qwt.QwtSymbol.Elipse the error would be caught before running.

If you code with strings like 'elipse' the error cannot be caught before runtime, and would only be caught when actually calling setSymbol (so if that call appear in an else branch you never take in your particular run, the error will stay unnoticed).

And of course, there are also performance reasons.

There are whole books on this typing question. You could e.g. learn a bit of Ocaml and read Types and Programming Languages by B.Pierce.

See also this question.

于 2011-12-31T09:06:25.893 に答える
0

質問が賛成したことに本当に驚いています。なんで?それは研究努力を示していますか?いいえ!OPは調査を行ったかもしれませんが、彼はそれを明らかにしませんでした。それは役に立ちましたか?はっきりしていますか?彼が匿名オブジェクトの受け渡しに問題があることは明らかです。しかし、なぜ知識を得るための彼の個人的な闘いが役立つのでしょうか?

単純な点線の灰色の楕円を作成するためだけに、なぜsuperfluosコードを入力するのにそれほど多くの「努力」をしなければならないのか疑問に思っています。まず、「Qt」ではオブジェクト指向のフレームワークを使用していることを覚えておく必要があります。したがって、用語と概念的には、オブジェクトをインスタンス化するクラスのセットを使用しています。タイプと呼ぶのはクラスです。

あなたの例では、次のことをしません。

grid.setPen(Qt.Pen)

これはsetPenにTYPEを渡しますが、 オブジェクトQt.Penを定義します。クラスとは異なり、オブジェクトには個別の値が含まれています:5(= )、0、3(= )。これは単純化しすぎですが、ポイントを家に帰すだけです。Qt.grayQt.DotLine

" type"integerが言うように、このタイプ(クラス)のすべてのオブジェクトは整数値を含むことができ、個々の値自体は含まれません。typeただし、 (クラス)のすべてのインスタンスがinteger整数値を保持する必要があることを定義しています。整数変数は、個々の値を持つクラスのインスタンス(オブジェクト)を保持します。

例に戻ると、クラス(タイプ)のオブジェクトを作成します。このオブジェクトはQtPen、メソッドsetPenが処理することを認識しています。

grid.setPen(Qt.QPen(Qt.Qt.gray、0、Qt.Qt.DotLine))

あなたのオブジェクトはたまたまclass(type)のものQt.Penです。したがって、 TYPEを渡すだけでなく、引数として明示的に言及した3つの値に加えて、オブジェクトで暗黙的に他の有用なもの(CapStyle、MiterLimit、JoinStyleなど)を1トン渡します。

Pythonでは、引数の暗黙的な型チェックはありません。だからあなたはあなたが提案したものを渡すことができます:

grid.setPen('gray'、0、'dotted')

ただし、このメソッドは、使い慣れたオブジェクトを想定しており、それらの処理方法を知っています。文字列-処理することがわからないオブジェクト。ですから、それが何をすべきかを説明するのはあなたの仕事でしょ。したがって、文字列を処理できるコンストラクターでサブクラス化Qt.Penするか、Qt.Penクラスを直接変更して後でQTを再コンパイルする必要があります。

Qt.Penクラスは最適な例ではないことを認めます。したがって、基礎となる概念と、誤った仮定の下にある場所を説明するためのより良い例を作成できます。

しかし、最初に、あなたの「代理」の質問は、オブジェクト指向のパラダイムを理解するための大きな混乱から生じていると主張しますが、より深い洞察がないため、混乱の原因を識別できませんでした-それは鶏が先か卵が先かという問題です。

ローマへの道はたくさんありますが、あなたが決めるのはあなたです。しかし、「Qt」を使用するという決定により、あなたはすでに一般的な道路のセットを決定しました。そして、それらはオブジェクト用に構築されています。

家をいくつか描きたいとしましょう。したがって、 (ちなみに、元の質問で探していたものとまったく同じです)をdraw_house使用してメソッドを定義します。magical_drawing_routine

def draw_house(house):
        magical_drawing_routine(house)

draw_house('parentshome')
draw_house('myhome')

これで、ドア、窓、または実家の素敵な煙突のない、まったく同じ2つの描かれた家ができました。magical_drawin_routine(そして、文字列値を解釈する方法を知っている方法を完全に無視しています)

製図板に戻って、これらの欠如を修正します。

def draw_house(door, window, chimney):
    magical_drawing_routine(door, window, chimney)

parentshome = ['oak', 'green', 'yes']
myhome = ['beech', 'red', 'no']
draw_house(parentshome)
draw_house(myhome)

これで、ドア、窓、そして実家の素敵な煙突が付いた、まったく同じ2つの描かれた家ができました。しかし、待ってください。窓とドアはまったく同じ形をしています。ふりだしに戻る...

いくつかのサイクルの後、あなたは次のようなものを持っているでしょう:

def draw_house(doormaterial, doorcolor, doorshape, doorwithglass, doorglassparts, windowsnumber, widnowsdistributionpattern, windowsencassing, windowmaterial, windowshape, windowpattern, windowdecoration, chimney):
   ...

class House, class Window, class Door, class Chimneyまたは、適切なデフォルト値を使用してクラスを定義することもできます。

pdoor, mdoor = Door(a,b), Door(a,Z) 
pwin, mwin = Window(e,f,g), Window(e,f,Y)
pchimney, mchimney = Chimney(h), Chimney(X)

parentshome = House(pdoor, pwin, pchimney)
myhome = House(mdoor, mwin, mchimney)

親のドアを1回だけ使用する場合は、匿名オブジェクト(変数がアタッチされていない)を生成することにより、pdoor定義を省略し、引数を渡しながらオブジェクトをオンザフライでインスタンス化できます。parentshome= House(Door(。 ..)、...)

したがって、簡単な答えは次のとおりです。型を渡さないでください。通常は複雑さをカプセル化するオブジェクトを渡します。しかし、ひどい単純なオブジェクトの場合、それはあなたの過度に複雑な単純なもののように見えるかもしれません-しかし、それはまさにそれがどのように見えるかです。

于 2011-12-31T09:20:03.917 に答える