python-3.xpydantic

How to Define Class Attributes after Inheriting Pydantic's BaseModel?


In normal python classes I can define class attributes like

class Example:
  x = 3
  def __init__(self):
    pass

And if I then do Example.x or Example().x, I get 3.

When I inherit pydantic's BaseModel, I can't figure out how to define class attributes, because the usual way of defining them is overwritten by BaseModel.

For example:

class Example(BaseModel):
  x = 3

print(Example.x)
--> type object 'Example' has no attribute 'x'

I want to be able to define class level attributes. What is the proper method/syntax for this?


Solution

  • Okey-dokey, I eventually got to the bottom of it. The answer lies with how dataclasses handle class variables. (In retrospect that should have been obvious, but ya live and ya learn)

    There exists a type called ClassVar. When a class's attribute is typed with ClassVar, then it becomes a class variable. (See: pydantic docs)

    
    from typing import ClassVar
    
    class Example(BaseModel):
      x: ClassVar[int] = 3
      y: int
    
    
    # Usage
    print(Example().x)
    >>> ValidationError
    
    print(Example.x)
    >>> 3