I want to make sure, that one of the arguments, passed when class creation is of certain type. Here is an example:
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class ListItems:
items: list | str | int | ListItems
class PList:
def __init__(self, name: str, items: ListItems):
self.type = "list"
self.name = name
self.items = items
a = PList('asd', ['asd'])
The idea was next: items
can only be list of string
, int
data type or other list of string
and int
, and it's nested. For example:
[] OK
[1,2,'asd'] OK
[[1,2,3],'asd',[]] OK
[{}] NOT OK
['test', [{}]] NOT OK
Is it possible to implement something like this in Python?
I am not really familiar with Python OOP, but from what I have found, there is no native implementation of interfaces and/or abstract class like in other programming languages.
PS: The code you see, was just my attempt of implementation, it did not work.
CodePudding user response:
def __init__(self, name: str, items: ListItems):
the items: ListItems
bit is saying that items
should be a ListItems
object, it's not passing through the logic of what ListItems
is doing, it's literally just comparing what type it is.
i don't have much experience with typing, but i think you're looking for items: list[str|int]
note that for lists, there is the normal list type hint, and then there's also one in the typing library. not sure if there's a difference, i just know that the normal list type hint is lowercased (list
and not List
like in the typing library), and that it is relatively new (3.11 i think)
CodePudding user response:
Short answer to your question Python is a dynamically typed language. It doesn’t know about the type of the variable until the code is run. So declaration is of no use. What it does is, It stores that value at some memory location and then binds that variable name to that memory container. And makes the contents of the container accessible through that variable name. So the data type does not matter. As it will get to know the type of the value at run-time.
Names are bound to objects at execution time by means of assignment statements, and it is possible to bind a name to objects of different types during the execution of the program. Functions and objects can be altered at runtime.
In a dynamically typed language, a variable is simply a value bound to a name; the value has a type -- like "integer" or "string" or "list" -- but the variable itself doesn't. You could have a variable which, right now, holds a number, and later assign a string to it if you need it to change. In a statically typed language, the variable itself has a type; if you have a variable that's an integer, you won't be able to assign any other type of value to it later.
From the following point you will find that predefining the datatype explicitly in python code won't enforce it to only accept this type:
(since type errors are a small fraction of all the things that might go wrong in a program); as a result, programmers in dynamic languages rely on their test suites to catch these and all other errors, rather than using a dedicated type-checking compiler.
Check this reference for more info.
CodePudding user response:
Specifying input type isn't a thing in Python the way it is in TypeScript. I'm not sure you even need the class listItems. Just use a simple if statement in your init method.
class PList:
def __init__(self, name, items):
self.type = 'list'
self.name = name
if type(items) is list or type(items) is str or type(items) is int:
self.items = items