Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
wobei "A.b" die Datei "A_b.pyd" ist usw.. Wenn ich in meinem Programm "A.pyd" importiere dann werden die Referenzen A_b.pyd nicht gefunden.
Hat jemand eine Idee wie ich das angehen kann? Am liebsten mit einer __init__.py. Aber wie?
@kap25: Also ich habe das Problem nicht verstanden. Wenn Du in einem Modul das `A` heisst ``import A.b`` zu stehen hast, dann wird versuchst aus diesem Modul A das Objekt mit dem Namen `b` zu importieren. Das sich im Modul `A` befinden muss. Aber dann braucht man es dort nicht zu importieren, denn es befindet sich dort ja bereits. Sofern der Import *nach* der Definition von `b` kommt. Sonst gibt es `b` zu dem Zeitpunkt ja noch nicht.
Kannst Du ein minimales, lauffähiges Beispiel von dem Problem zeigen?
ich glaube das sind Biblieotheken die aus einer anderen Sprache übersetzt wurden. Zur Laufzeit wurde das Problem mit "sitecustomize.py" und "sys.meta_path" gelöst. Hier der Code von "sitecustomize.py:
import importlib.machinery
import os, sys
class IILoader(importlib.machinery.ExtensionFileLoader):
def load_module(self, fullname):
return super(IILoader, self).load_module(fullname)
automation_namespaces = []
class MetaPathHook():
def __init__(self):
self.path = list()
ii_base_dir = os.getenv('II_LIB_PATH')
self.path.append(ii_base_dir)
automation_namespaces.append('A')
def find_module(self, fullname, path):
for namespace in automation_namespaces:
namespace_dot = namespace + '.'
if fullname == namespace or fullname.startswith(namespace_dot):
return self
return None
def load_module(self, fullname):
libname = fullname
for namespace in automation_namespaces:
namespace_dot = namespace + '.'
namespace_dash = namespace + '_'
if libname.startswith(namespace_dot):
libname = fullname.replace(namespace_dot, namespace_dash, 1)
module_ext = '.pyd'
libname = libname + module_ext
for p in self.path:
lib = os.path.join(p, libname)
if os.path.exists(lib):
loader = IILoader(fullname, lib)
module = loader.load_module(None)
module.__path__ = "IIPackagePath"
try:
module._handle_import(module)
except:
print("could not call _handle_import", module)
return module
raise ImportError(fullname)
sys.meta_path.insert(0, MetaPathHook())
Wenn ich die Shell starte und 'import A' eingebe, dann funktioniert alles. Nur beim programieren in PyCharm funktioniert die Vervollständigung nicht. Weil bei der Erstellung von "Binary Skeletons" die imports nicht gefunden werden.
@kap25: Ich wüsste nicht was man da machen kann bzw. was Du da jetzt eigentlich machen *willst*. Da werden Module importiert die irgendwo liegen können und in ein einer Verzeichnisstruktur und mit Namen die nicht dem Standard entsprechen. Dazu gibt's Code der das dynamisch auf eine Package/Modulhierarchie bei Bedarf, also beim importieren, abbildet. Das lässt sich statisch nicht analysieren (solange man nur von Standardimportmechanismen ausgeht), also funktioniert eine Autovervollständigung nicht, ohne tatsächlich zu importieren.
Ich glaube Pycharm kennt irgendein Dateiformat in dem die Signaturen etc. gespeichert werden und mit dessen Hilfe man der IDE auch solche Informationen beibringen kann die sich nicht statisch ermitteln lassen, entweder wegen solcher dynamischen Importmechanismen oder weil sich die API nicht untersuchen lässt. (C-Erweiterungen müssen nicht alle Informationen liefern die man von reinen Python-Objekten abfragen kann.)
Du könntest also versuchen selbst Introspection-Code zu schreiben der solche Dateien erstellt.
PyCharm verwendet „python skeletons“ um die Autovervollständigung zu verbessern. Das sind einfach Python-Dateien mit den entsprechenden Annotationen die statisch analysiert werden können: https://github.com/JetBrains/python-skeletons