2

How can I cast a var into a CustomClass?

In Python, I can use float(var), int(var) and str(var) to cast a variable into primitive data types but I can't use CustomClass(var) to cast a variable into a CustomClass unless I have a constructor for that variable type.

Example with inheritance.

class CustomBase:
    pass

class CustomClass(CustomBase):
    def foo():
        pass

def bar(var: CustomBase):
    if isinstance(var, CustomClass):
        # customClass = CustomClass(var)   <-- Would like to cast here...
        # customClass.foo()                <-- to make it clear that I can call foo here.
lachy
  • 1,833
  • 3
  • 18
  • 27
  • Can you clarify what you are trying to do? ``if isinstance(var, CustomClass)`` already guarantees that ``var`` "is a" ``CustomClass`` in the branch. There is no need to "cast" ``var`` to a ``CustomClass``, since it already is one. Be aware that ``float(var)`` etc. work precisely because ``float`` etc. have a constructor specifically made to deal with various types (namely those implementing ``__float__`` etc.). – MisterMiyagi Jan 04 '21 at 15:08
  • @MisterMiyagi I realised what I was after was actually the static type casting to be correct for variables that I now know are a certain type so that I can use my IDE's tools for working with those variables (eg. autocomplete and static type checking). The original question doesn't reflect this and I do need to update it. – lachy Jan 08 '21 at 22:35

1 Answers1

2

In the process of writing this question I believe I've found a solution.

Python is using Duck-typing

Therefore it is not necessary to cast before calling a function.

Ie. the following is functionally fine.

def bar(var):
    if isinstance(var, CustomClass):
        customClass.foo()

I actually wanted static type casting on variables

I want this so that I can continue to get all the lovely benefits of the typing PEP in my IDE such as checking function input types, warnings for non-existant class methods, autocompleting methods, etc.

For this I believe re-typing (not sure if this is the correct term) is a suitable solution:

class CustomBase:
    pass

class CustomClass(CustomBase):
    def foo():
        pass

def bar(var: CustomBase):
    if isinstance(var, CustomClass):
        customClass: CustomClass = var
        customClass.foo()  # Now my IDE doesn't report this method call as a warning.

lachy
  • 1,833
  • 3
  • 18
  • 27
  • 2
    What you have described as "pythonic" is actually *not* pythonic. You should normally not do an explicit type check (and if you must, `isinstance(var, CustomClass)` is preferred over `type(var) == CustomClass`). Just use `var.foo()` and *assume* that the `var` object has this method. That's what "duck-typing" means. – mkrieger1 Jan 02 '21 at 20:59
  • Ok good point, I'm just going to remove the reference to what is Pythonic and update to be more in line with your suggestion. – lachy Jan 02 '21 at 21:03