1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Template classes in Python

Discussão em 'Python' iniciado por Stack, Julho 25, 2025.

  1. Stack

    Stack Membro Participativo

    I'm attempting to create algebras in Python, and I'm finding it difficult to create parameterized classes.

    As an example, consider this ProductWeight class. It holds two other Weight objects, with enforced types (at least statically, via mypy).

    This will fail because (by design) I cannot access the classes for W1 and W2 to call their classmethods like zero. (They're not specified; ProductWeight is not templated.) ProductWeight doesn't know, when I create an instance, which types to bind to it.

    from typing import Generic, TypeVar
    W1 = TypeVar("W1")
    W2 = TypeVar("W2")

    class ProductWeight(Generic[W1, W2]):
    def __init__(self, value1: W1, value2: W2):
    self.value1_ = value1
    self.value2_ = value2

    @classmethod
    def zero(cls):
    return cls(W1.zero(), W2.zero()) # Will fail - no access to W1 and W2.



    By contrast, this is straightforward in C++: because the type is parameterized, it is able to look up W1::Zero.

    template<typename W1, typename W2>
    public:
    ProductWeight(W1 w1, W2 w2) : value1_(w1), value2_(w2) {}
    static ProductWeight Zero() {
    return ProductWeight(W1::Zero(), W2::Zero());
    }
    private:
    W1 value1_;
    W2 value2_;
    };


    Is there a workaround for this in Python? Either creating an inner class, or otherwise somehow providing types to the class (rather than to class instances)?

    For the sake of a minimal reproducible example, you can use this implementation of another Weight type.

    class SimpleWeight:
    def __init__(self, value):
    assert value in {True, False}
    self.value_ = value

    @classmethod
    def zero(cls):
    return cls(False)

    weight1 = SimpleWeight(False)
    weight2 = SimpleWeight(True)
    product = ProductWeight(weight1, weight2)

    print(SimpleWeight.zero()) # So far, so good.
    print(ProductWeight.zero()) # Oof.
    # Predictably, it failed because `ProductWeight` is not specialized.


    And here's the predictable error message:

    Traceback (most recent call last):
    File "garbage.py", line 32, in <module>
    print(ProductWeight.zero()) # Oof.
    File "garbage.py", line 14, in zero
    return cls(W1.zero(), W2.zero()) # Will fail - no access to W1 and W2.
    AttributeError: 'TypeVar' object has no attribute 'zero'


    Ideally, it would be possible to create a parametric type like this:

    product = ProductWeight[SimpleWeight, SimpleWeight](weight1, weight2)
    # And similarly:
    print(ProductWeight[SimpleWeight, SimpleWeight].zero())

    Continue reading...

Compartilhe esta Página