In fact you can achieve something similar to private members by taking advantage of scoping. We can create a module-level class that creates new locally-scoped variables during creation of the class, then use those variables elsewhere in that class.
class Foo:
    def __new__(cls: "type[Foo]", i: int, o: object) -> "Foo":
        _some_private_int: int = i
        _some_private_obj: object = o
        foo = super().__new__(cls)
        def show_vars() -> None:
            print(_some_private_int)
            print(_some_private_obj)
        foo.show_vars = show_vars
        return foo
    def show_vars(self: "Foo") -> None:
        pass
We can then do, e.g.
foo = Foo(10, {"a":1})
foo.show_vars()
# 10
# {'a': 1}
Alternatively, here's a poor example that creates a class in a module that has access to variables scoped to the function in which the class is created. Do note that this state is shared between all instances (so be wary of this specific example). I'm sure there's a way to avoid this, but I'll leave that as an exercise for someone else.
def _foo_create():
    _some_private_int: int
    _some_private_obj: object
    class Foo:
        def __init__(self, i: int, o: object) -> None:
            nonlocal _some_private_int
            nonlocal _some_private_obj
            _some_private_int = i
            _some_private_obj = o
        def show_vars(self):
            print(_some_private_int)
            print(_some_private_obj)
    import sys
    sys.modules[__name__].Foo = Foo
_foo_create()
As far as I am aware, there is not a way to gain access to these locally-scoped variables, though I'd be interested to know otherwise, if it is possible.