
{"id":4744,"date":"2020-06-01T00:15:58","date_gmt":"2020-06-01T04:15:58","guid":{"rendered":"https:\/\/ikriv.com\/blog\/?p=4744"},"modified":"2020-06-01T00:23:16","modified_gmt":"2020-06-01T04:23:16","slug":"type-cast-in-python","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=4744","title":{"rendered":"Type cast in Python"},"content":{"rendered":"<p><b>TL;DR<b>:<br \/>\nPython type cast looks like an assertion:<\/b><\/b><\/p>\n<pre><span style=\"color:darkgreen\"># Python<\/span>\r\nx = expression_returning_Base\r\n<b>assert isinstance(x, Derived)<\/b><\/pre>\n<p>This corresponds to Java or C#<\/p>\n<pre><span style=\"color:darkgreen\">\/\/ Java<\/span>\r\nDerived x = <b>(Derived)<\/b>expression_returning_Base;<\/pre>\n<p>In languages like Java and C++, it is a common situation when at runtime we know we have an object of type <code>Derived<\/code>, but the compiler thinks it is of type <code>Base<\/code>, so we must explicitly <i>cast<\/i> the object reference to type <code>Derived<\/code> before the compiler would allow us to use any <code>Derived<\/code>-specific properties or methods.<\/p>\n<p>Python, being a dynamic type language, does not have this problem: you just call whatever methods you feel right. If such methods are not found at runtime, an exception will occur.<\/p>\n<pre><span style=\"color:darkgreen\"># Python<\/span>\r\nclass Base:\r\n  def foo(self) -> None:\r\n    print(\"Base.foo()\")\r\n\r\nclass Derived(Base):\r\n  def bar(self) -> None:\r\n    print(\"Derived.bar()\")\r\n\r\ndef func() -> Base:\r\n  return Derived()\r\n\r\nx = func()\r\n<b>x.bar()<\/b> <span style=\"color:darkgreen\"># it works, but fails the type check<\/span><\/pre>\n<p>However, the situation changes in presence of type hints: <code>x.bar()<\/code> above won&#8217;t pass the type check, claiming that <code style=\"color:red\">\"Base\" has no attribute \"bar\"<\/code>. This does not prevent us from running the code, but may, say, prevent from committing it to a repo if type checks are strictly enforced.<\/p>\n<p>If we simply declare <code>x<\/code> of type <code>Derived<\/code>, it does not help:<\/p>\n<pre><b>x : Derived<\/b> = func() <span style=\"color:darkgreen\"># typecheck error<\/span>\r\nx.bar()<\/pre>\n<p>The error is <code style=\"color:red\">Incompatible types in assignment (expression has type \"Base\", variable has type \"Derived\")<\/code>.<\/p>\n<p>To convince the type checker that <code>x<\/code> is indeed of type <code>Derived<\/code>, we need an assertion:<\/p>\n<pre>x = func() \r\n<b>assert isinstance(x, Derived)<\/b> <span style=\"color:green\"># type cast<\/span>\r\nx.bar()<\/pre>\n<p>Note, that the situation may become complicated if you apply type assertion to attributes. Unlike C++ or Java, type checking is not part of the language runtime, so whether the assert will work depends on the type checker.<\/p>\n<pre>x = type('test', (), {})() <span style=\"color:darkgreen\"># empty object of custom type<\/span>\r\nx.y = func()\r\n<b>assert isinstance(x.y, Derived)<\/b>\r\nx.y.bar() <span style=\"color:darkgreen\"># May or may not pass the type check<\/span><\/pre>\n<p>Specifically, current version of <a href=\"http:\/\/mypy-lang.org\/\">mypy<\/a> recognizes this assert, but <a href=\"https:\/\/pyre-check.org\/\">pyre<\/a> does not.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR: Python type cast looks like an assertion: # Python x = expression_returning_Base assert isinstance(x, Derived) This corresponds to Java or C# \/\/ Java Derived x = (Derived)expression_returning_Base; In languages <a href=\"https:\/\/ikriv.com\/blog\/?p=4744\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[1],"tags":[],"class_list":["entry","author-ikriv","post-4744","post","type-post","status-publish","format-standard","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4744","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4744"}],"version-history":[{"count":8,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4744\/revisions"}],"predecessor-version":[{"id":4752,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4744\/revisions\/4752"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}