Можно ли ссылаться на тип в Python - PullRequest
0 голосов
/ 13 марта 2019

Я хочу сделать что-то вроде этого:

@attr.s
class A(object):
    a_dict = attr.ib(factory=Dict, type=Dict[str, A], validator=optional(instance_of(Dict)))

Возможно набрать его просто как type=Dict, но мне интересно, можете ли вы ссылаться на себя как type=Dict[str, cls], но это может быть ограничено возможностями Python.

Спасибо.

Ответы [ 3 ]

1 голос
/ 14 марта 2019

Проблема в том, что class A(object): A приводит к NameError: name 'A' is not defined. Это означает, что нельзя ссылаться на класс по его имени во время его создания в его определяющем блоке.

Я думаю, что, чтобы обойти это при наборе текста, можно вместо этого использовать строку: type=Dict[str, 'A']. Я помню, как видел, как делаются прямые ссылки, но это может быть неправильно.

1 голос
/ 22 марта 2019

Если я правильно истолковываю, вы хотите вот что:

from typing import Dict, Optional

import attr

from attr.validators import optional, instance_of


@attr.s
class A(object):
    a_dict = attr.ib(
        factory=dict,
        type=Optional[Dict[str, "A"]],
        validator=optional(instance_of(dict))
    )


A({"key": A(None)})

И это проходит mypy.

Обратите внимание:

  • Вы не можете использовать typing.Dict для factory, потому что это действительно только для подсказок типа и завершается ошибкой, если вы пытаетесь создать его экземпляр.
  • instance_of использует isinstance() для внутреннего использования, и хотя isinstance({}, Dict) имеет значение True, я не думаю, что он предназначен для такого использования.
  • Если a_dict является необязательным для валидатора, вам также нужно объявить его необязательным, используя аннотации типов, заключив его в Optional[].
1 голос
/ 14 марта 2019

cls и self - это имена, данные классам и их экземплярам по соглашению, когда они передаются в качестве аргументов методам класса и методам экземпляра соответственно. Ни один из них не будет определен, где вы пытаетесь их использовать.

Вместо этого вы можете сделать так, чтобы тип был необъектным суперкласс из A, если он есть.

...