質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3869閲覧

C#からPythonへの書き換え、キャストについて

SKEK

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/11/13 21:06

前提・実現したいこと

お世話になります。
C#は全くの初心者なのですが、C#で頂いたコードをPythonに書き換えたいと思っています。
書き換えたいコードは以下のコードです。

Test1 AS = Test as Test1

Testは基底クラスで、Test1はその派生クラスです。
これが、たぶんダウンキャストと言われるものだろうというとこまではわかったのですが、
Pythonでこのコードが再現できるのかどうかがわかりません。再現できるのでしょうか?
再現できる場合は、その方法をご教授頂きたいです。

試したこと

以下のリンクを参照して、トライしましたが、うまくいきませんでした。
両方のクラスとも__slots__ はもっていません。
http://nihaoshijie.hatenadiary.jp/entry/2014/08/09/152558
また、以下のリンクではPythonではクラスキャストは再現できないと記載されています。
https://qiita.com/_Nanagin/items/f8afd1432b7327ad885e

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tachikoma

2018/11/13 22:07

たぶんその部分無視(省略)してもいいと思うけど、もう少し前後の文脈をコードで教えて下さい。
guest

回答2

0

ベストアンサー

結論から言えば「おおきく道を間違えている」といえると思います。

参照しておられるサイトは(大変失礼かつ生意気な言いようですが)Pythonの型システムの設計に踏み込んだ議論が不足していると思います。(スミマセン、元の記述は言い方がおかしかったので訂正しました)。

Pythonでは動的なインスタンスの改変をかなり「ゆるく」許しており「型を表す重要なフィールドである__class__も場合によっては簡単に改変できる」ようになっています。しかしながら「それを変更することで何が起きるかは言語システムでは何も保証していないに近い」です。

python

1def cast(clazz, instance): 2 instance.__class__ = clazz 3 4class A: 5 def __init__(self, value): 6 self.value = value 7 8 def get(self): 9 return self.value 10 11 def __repr__(self): 12 return '#<A: value={}>'.format(self.value) 13 14class B: pass 15 16b = B() 17print(type(b)) # => <__main__.B at ...> 18case(A, b) 19print(type(b)) # => <__main__.A at ...> Aのインスタンスになったかのように見えるが 20print(b) # => 例外 21print(b.get()) # => 例外 22b.value = 1 23print(b.get()) # => 1 24print(b) # => #<A: value=1>

ちなみにcastした後、b.valueに1を設定なんてことをしてますが、それをしさえすればいいかという単純な話でもありません。classの定義のしかたによって上記のような程度ではすまず、手が付けられない状況にもなることもあるでしょう。

要するに単に__class__を変えたらインスタンスが他のクラスに化けてくれるなんてことはありません。これはPythonの型システムを熟知したプログラマーが新たにメタクラスやそれに関連したデコレータなどのメタプログラミングをする際に使うもので、普通のアプリケーションを作る際に手をだすようなものではないと思います。

さてそもそもC#のような静的型付け言語におけるダウンキャストとは

「ある基底クラスに属するインスタンスが、そのクラスの特定の派生クラスのインスタンスであるかどうかを検査し、そうであるなら成功、そうでないなら失敗(失敗動作は例外の発生だったり、つじつまを合わせるために結果をnullにしたり)させること」です。

決して「基底クラスの派生クラスでないものを無理やり派生クラスに改変する」ようなものではありません。全然目的が違うのです。


補足: 結論を言い忘れました。(じゃなくて...)C#のasをそのまままねするなら次のようにすべきと思います。

Python

1a = some_function() # AまたはAの派生のBのインスタンスを返すような関数 2b = a if isinstance(a, B) else None 3# もしaがBのインスタンスならbにはそのインスタンスが設定されそうでなければNoneが設定される

投稿2018/11/14 03:46

編集2018/11/14 03:58
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/11/14 04:09

よく推敲する前に投稿してしまい立て続けに編集してしまいました。質問者さんにアドバイスする前に、自分こそ考えを整理したり文章をまとめる訓練しなきゃです。失礼いたしました。
SKEK

2018/11/14 20:00

ご丁寧にご回答くださりありがとうございました。 ダウンキャストのご説明がとても分かりやすく勉強になりました。
guest

0

そもそもダックタイピングの言語でキャストとか要らないと思うんですが・・・

投稿2018/11/13 22:29

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SKEK

2018/11/14 21:24

コメントして頂きありがとうございました。勉強になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問