user14030237
user14030237

Reputation: 41

Casting Constructor in Python

I'm using stricly typed Python, and would like to achieve something similar to the copy/move constructor overloading of C++. That is, I'd like to make my object convertible to another type using an explicit definition.

Here's an example:

class CallerSurface(StringEnum):
  IOS_APPLICATION = "ios_application"
  ANDROID_APPLICATION = "android_application"
  WEB_APPLICATION = "web_application"

which I can use with some function such as:

  def getResponse(data: Data, caller_name: CallerSurface) -> str:

I'd like to add some part of the definition of class CallerSurface to make it possible for a function that takes a param of type CallerSurface, to also take a param of type str, and just "know" how to convert the str to CallerSurface without the programmer needing to explicitly figure out a conversion.

So I want to use in the following way:

  caller_name: str = HTTPUtils.extractCallerFromUserAgent(request)
  response = getResponse(other_data, caller_name)

caller_name is a str, but getResponse takes a CallerSurface. I'd like to make the conversion be implicitly defined in then CallerSurface class.

In C++ you could achieve this by defining a copy and a move constructor that takes in string. Is there something in Python for this?

Upvotes: 1

Views: 473

Answers (2)

Samwise
Samwise

Reputation: 71464

Python doesn't do type conversion implicitly. It does provide things like the __str__ magic method, but that conversion still requires an explicit call to the str() function.

What you want to do, I think, is leave the typing as CallerSurface, and use a static type checker to force the caller to do (e.g.):

  caller_name = HTTPUtils.extractCallerFromUserAgent(request)
  response = getResponse(other_data, CallerSurface(caller_name))

Using a type checker (e.g. mypy) is key, since that makes it impossible to forget the CallerSurface call (or whatever other kind of conversion needs to happen).

Upvotes: 1

ShadowRanger
ShadowRanger

Reputation: 155438

There is no way to automate the conversion (there's no such thing as implicit type conversion of the sort you're looking for), so your options are:

  1. Expand the allowed argument types (caller_name: CallerSurface becomes caller_name: Union[CallerSurface, str]), manually convert the related types to the intended type, or
  2. Use @functools.singledispatch to make multiple versions of the function, one that accepts each type, where all but one implementation just converts to the intended type and calls itself

In short, this isn't C++, and implicit type conversions aren't a thing in the general case.

Upvotes: 1

Related Questions