Существующий класс не в директории - PullRequest
0 голосов
/ 26 января 2020

Я хотел понять (части) дерева наследования sympy. Для этого я сделал

1 b = sym.Symbol('b')
2 print(type(b))
3 print(dir(sympy.core))
4 print(dir(sympy.core.symbol))

<class 'sympy.core.symbol.Symbol'>
['BasicMeta', 'Registry', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'all_classes', 'division', 'ordering_of_classes', 'print_function']
...
AttributeError: module 'sympy.core.core' has no attribute 'symbol'

. Из результата строки 2 я ожидал, что symbol будет в списке, напечатанном в строке 3. А потом я ожидал, что Symbol будет в напечатанном списке. в строке 4.

Но первого не произошло, выдав ошибку. И строка 4 даже не выполнялась.

Почему это так? Как справиться с безотказной работой в таких случаях, как это? Что мне делать, чтобы осмотреть дерево наследования о Symbol?

1 Ответ

1 голос
/ 26 января 2020

Смешение стилей импорта в базе кодов sympy сбивает с толку. На самом деле это уже изменилось с момента последнего выпуска, поэтому выполнение вашего примера на sympy master дает:

<class 'sympy.core.symbol.Symbol'>
['Add', 'AlgebraicNumber', 'Atom', 'AtomicExpr', 'Basic', 'Catalan', 'Derivative', 'Dict', 'Dummy', 'E', 'Eq', 'Equality', 'EulerGamma', 'Expr', 'Float', 'Function', 'FunctionClass', 'Ge', 'GoldenRatio', 'GreaterThan', 'Gt', 'I', 'Integer', 'Lambda', 'Le', 'LessThan', 'Lt', 'Mod', 'Mul', 'N', 'Ne', 'Number', 'NumberSymbol', 'PoleError', 'Pow', 'PrecisionExhausted', 'Rational', 'RealNumber', 'Rel', 'S', 'StrictGreaterThan', 'StrictLessThan', 'Subs', 'Symbol', 'SympifyError', 'TribonacciConstant', 'Tuple', 'Unequality', 'UnevaluatedExpr', 'Wild', 'WildFunction', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'add', 'alphabets', 'arity', 'assumptions', 'basic', 'cache', 'cacheit', 'comp', 'compatibility', 'containers', 'core', 'coreerrors', 'count_ops', 'decorators', 'diff', 'evalf', 'evaluate', 'expand', 'expand_complex', 'expand_func', 'expand_log', 'expand_mul', 'expand_multinomial', 'expand_power_base', 'expand_power_exp', 'expand_trig', 'expr', 'exprtools', 'factor_nc', 'factor_terms', 'facts', 'function', 'gcd_terms', 'igcd', 'ilcm', 'integer_log', 'integer_nthroot', 'logic', 'mod', 'mod_inverse', 'mul', 'multidimensional', 'nan', 'nfloat', 'numbers', 'oo', 'operations', 'parameters', 'pi', 'power', 'preorder_traversal', 'prod', 'relational', 'rules', 'seterr', 'singleton', 'symbol', 'symbols', 'sympify', 'var', 'vectorize', 'zoo']
['AtomicExpr', 'Basic', 'Boolean', 'Dummy', 'Expr', 'FunctionClass', 'S', 'StdFactKB', 'Symbol', 'Tuple', 'Wild', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_assume_defined', '_filter_assumptions', '_range', '_re', '_symbol', '_uniquely_named_symbol', 'cacheit', 'cartes', 'disambiguate', 'division', 'fuzzy_bool', 'is_sequence', 'ordered', 'print_function', 'random', 'sift', 'string', 'symbols', 'sympify', 'var']

Причина путаницы заключается в том, что (в sympy 1.5.1):

  1. sympy/__init__.py делает from sympy.core import *
  2. sympy/core/__init__.py не определяет __all__
  3. В базовом пакете есть субмодуль под названием core (sympy.core.core).

Поэтому, когда вы делаете sympy.core в 1.5.1, вы на самом деле получаете модуль sympy.core.core от sympy/core/core.py, тогда как на мастере он правильно дает пакет sympy.core.

Более прямой путь чтобы получить модуль

>>> import sympy as sym
>>> b = sym.Symbol('b')
>>> b.__module__
'sympy.core.symbol'
>>> import sys
>>> sys.modules[b.__module__]
<module 'sympy.core.symbol' from 'sympy/core/symbol.py'>```

Я бы просто открыл sympy/core/symbol.py, если бы хотел посмотреть, что там находится.

Для изучения деревьев наследования вы можете найти mro полезным:

>>> type(b).mro()
[<class 'sympy.core.symbol.Symbol'>, <class 'sympy.core.expr.AtomicExpr'>, <class 'sympy.core.basic.Atom'>, <class 'sympy.core.expr.Expr'>, <class 'sympy.logic.boolalg.Boolean'>, <class 'sympy.core.basic.Basic'>, <class 'sympy.core.evalf.EvalfMixin'>, <class 'object'>]
...