2016-04-12 24 views
4

Örnek yerine bir sınıf döndüren python işlevim var. Döndürülen değerin belirli bir türden bir alt sınıf olduğunu nasıl belirtirim? (Tip kontrol edilmiş iade sınıfı PEP 484

from typing import Dict, Any 

def class_constructor(name: str, attrs: Dict[str, Any]) -> type 
    ConstructedClass = type(name, (BaseClass,), attrs) 
    return ConstructedClass 

class BaseClass: ... 

Söyleyemem ...: Aşağıdaki örnekte

Ben türü olarak dönüş değeri, ancak daha ileri tipi BaseClass tüm niteliklerini sahip olduğunu belirtmek isteriz) -> Bu yana BaseClass BaseClass kendisi yerine bir BaseClass örneğini gösterir.

Kendi sorumu yanıtlamak için, bu python/typing issue #107 olarak görünür. Şimdilik, en iyi çözümdür: Eğer __init__ imza biliyorsanız

from typing import Dict, Any 

class BaseClass: ... 

def class_constructor(name: str, attrs: Dict[str, Any]) -> Callable[Any, BaseClass] 
    ConstructedClass = type(name, (BaseClass,), attrs) 
    return ConstructedClass 

, sen Callable[Any, ...] o yerine Any kullanabilirsiniz. Type[T] için destek çözüm olacaktır eklenir

:

from typing import Dict, Any 

class BaseClass: ... 

def class_constructor(name: str, attrs: Dict[str, Any]) -> Type[BaseClass] 
    ConstructedClass = type(name, (BaseClass,), attrs) 
    return ConstructedClass 
+0

İstediğiniz şeyi yapmayan somut, çalıştırılabilir bir örnek sağlayabilir misiniz? – chepner

+0

Her ikisi de mypy ve PEP 484'te 'Type [T]' desteği eklenir. – max

cevap

0

Ben sadece onu etiketleme bir yolu ve herhangi soyundan sınıfları olarak BaseClass tarafından kullanılan yeni bir sınıf oluşturmak gerekir diye düşünüyorum.

class BaseClassMeta(type): 
    pass 

class BaseClass(metaclass=BaseClassMeta): 
    ... 

def class_constructor(name: str, attrs: Dict[str, Any]) -> BaseClassMeta 
    ConstructedClass = BaseClassMeta(name, (BaseClass,), attrs) 
    return ConstructedClass 
+0

Ortaya çıkan sınıf gerçekten uygun şekilde çalışır, ancak sorunu çözmez. 'BaseClassMeta (...)' bir tür üretir, ancak ConstructedClass (...) 'bir nesne üretir, bu nedenle döndürülen tür" BaseClassMeta "olamaz. İhtiyacım olan şeylere biraz daha yakın olabilirim -> Callable [[...], BaseClass] '' '' '' '' '' __init__' işlevinin argümanlarıdır. Bu kodun bütün mantıklı olması için sınıflar). En azından PyCharm, döndürülmüş sınıfın nitelikleri değilse “ConstructedClass (...)” nesnesinin niteliklerini çıkarır. – Neapolitan

+0

Neden değil? Aslında bir 'ConstructedClass' örneğini nerede oluşturuyorsunuz? Hem BaseClass hem de ConstructedClass, 'BaseClassMeta' örnekleridir. – chepner

+0

Sınıf yapıcısından gelen dönüş değeri gerçekten de 'BaseClassMeta' örneğidir, ancak farklı davranır. Yani, BaseClassMeta (...) -> type' ancak ConstructedClass (...) -> object'. Eğer 'class_constructor' '' BaseClassMeta' döndürdüğünü söylerseniz, 'MyClass = class_constructor (...)' kullanımıyla ilgili statik analiz daha sonra 'obj = MyClass()' '' BaseClassMeta' türünden' MyClass' ('' '' işlevi olarak aynı imzayı bekliyor. – Neapolitan