Mam system, który zwykle przechowuje typy kiszonych klas.Podlewanie podklasy o parametrach sparametryzowanych dynamicznie
Chcę móc zapisywać dynamicznie sparametryzowane klasy w ten sam sposób, ale nie mogę, ponieważ otrzymuję błąd PicklingError podczas próby pobrania klasy, która nie została znaleziona globalnie (nie zdefiniowano w prostym kodzie).
Mój problem można modelować jak w poniższym przykładzie kodu:
class Base(object):
def m(self):
return self.__class__.PARAM
def make_parameterized(param_value):
class AutoSubClass(Base):
PARAM = param_value
return AutoSubClass
cls = make_parameterized(input("param value?"))
Kiedy próbuję marynowane klasę, pojawia się następujący błąd:
# pickle.PicklingError: Can't pickle <class '__main__.AutoSubClass'>: it's not found as __main__.AutoSubClass
import pickle
print pickle.dumps(cls)
szukam jakiegoś sposobu zadeklaruj Base jako ParameterizableBaseClass
, który powinien zdefiniować potrzebne parametry (PARAM
w powyższym przykładzie). Podklasa z parametrami dynamicznymi (cls
) powinna być następnie dostępna do wybrania przez zapisanie typu "ParameterizableBaseClass" i różnych wartości parametrów (dynamiczny param_value
powyżej).
Jestem pewien, że w wielu przypadkach można tego całkowicie uniknąć ... I mogę tego uniknąć również w moim kodzie, jeśli naprawdę (naprawdę) muszę. W pewnym momencie grałem z __metaclass__
, copyreg
, a nawet __builtin__.issubclass
(nie pytam), ale nie mogłem go złamać.
Czuję, że nie byłbym wierny duchowi Pythona, gdybym nie pytał: w jaki sposób można to osiągnąć w stosunkowo czysty sposób?
W stosunkowo czysty sposób? Nie sądzę, że jest to możliwe dla jakiejkolwiek sensownej definicji "czystej". Dlaczego próbujesz pobierać obiekty, których klasy są generowane w czasie wykonywania? Jaki jest faktyczny przypadek użycia? Jak zamierzasz rozpruć coś, czego klasa nie istnieje? –
Ja też nie rozumiem tego przypadku. Dlaczego nie można po prostu zwrócić instancji klasy z tym parametrem jako atrybutu po inicjalizacji. Kolejny komentarz, należy także unikać magii Pythona, tj. 'Self .__ class __. PARAM'. Myślę, że to komplikujesz. – milkypostman
Może się zdarzyć, że jest to nadmierna komplikacja (w takim przypadku pytanie może nadal trwać, nawet bez względu na moją sprawę). Mój przykład wygląda na naprawdę niemądry - to tylko przykład. Mój prawdziwy system klasyfikuje typy klas wraz z parametrami tworzenia i przekazuje je między procesami w scenariuszu przetwarzania równoległego. Oprócz ~ 20 różnych używanych klas, z konkretnym kodem w każdym z nich, mam kilka klas "po prostu wybierz twój parametr". Chcę móc je podklasować dynamicznie, bez konieczności zmiany (i potencjalnie przeładowania) kodu i umożliwienia ich wybrania. HTH. – Yonatan