title: Python access dataclass default_factory field without instantiating it
body: <p>I have a classmethod <code>create_instance()</code> of a dataclass <code>Bar</code> that needs to check on a <code>field(default_factory=...)</code>-type parameter of the dataclass before returning an instance of the dataclass:</p>
  <pre><code>from dataclasses import dataclass, field
  from typing import Dict
  
  
  @dataclass
  class Bar:
      number: int
      static_dict: Dict[str, int] = field(
          default_factory=lambda: {
              'foo': 1,
          }
      )
  
      @classmethod
      def create_instance(cls) -&gt; 'Bar':
          access = cls.static_dict
          return cls(number=access['foo'])
  
  if __name__ == '__main__':
      foo = Bar.static_dict  # 1) fails already
      foo = Bar.create_instance()  # 2) fails too since it uses 1)
  </code></pre>
  <p>This fails with:</p>
  <p><code>AttributeError: type object 'Bar' has no attribute 'static_dict'</code></p>
  <p>Without type-hinting the return value, e.g.</p>
  <pre><code>@classmethod
  def create_instance(cls):
      access = cls.static_dict
      return cls(number=access['foo-1'])
  </code></pre>
  <p>if fails by mentioning the dataclass itself doesn't have the attribute:</p>
  <p><code>AttributeError: type object 'Bar' has no attribute 'static_dict'</code>.</p>
  <p>The same error would occur using a staticmethod e.g. with type hinting:</p>
  <pre><code>@staticmethod
  def create_instance_static() -&gt; 'Bar':
      access = Bar.static_dict
      return Bar(number=access['foo'])
  </code></pre>
  <p>My very ugly workaround is to define a global variable and pass it into the class, which lets me use the <code>create_instance()</code>-method:</p>
  <pre><code>from dataclasses import dataclass, field
  from typing import Dict
  
  GLOBAL_DICT = {
      'foo': 2,
  }
  
  
  @dataclass
  class BarWorkaround:
      number: int
      static_dict: Dict[str, int] = field(
          default_factory=lambda: GLOBAL_DICT
      )
  
      @classmethod
      def create_instance(cls) -&gt; 'BarWorkaround':
          access = GLOBAL_DICT
          return cls(number=access['foo'])
  
  
  if __name__ == '__main__':
      foo = BarWorkaround.create_instance()  # works as intended
  </code></pre>
  <p>Can't say I'm a fan of defining globals for something like this. My guess is something about the way dataclasses are constructed interferes with my accessing the static default attribute, but I don't get what it is.</p>