Создайте параметризованный тип в Python, но сделайте все экземпляры дочерними по отношению к & ldquo; super-type & rdquo;

В контексте использования в языках регулярные выражения действуют на строки, а не на строки. Таким образом, вы должны нормально использовать регулярное выражение, считая, что входная строка имеет несколько строк.

В этом случае заданное регулярное выражение будет соответствовать всей строке, так как «& lt; FooBar & gt;» настоящее. В зависимости от специфики реализации регулярного выражения значение $ 1 (полученное из «(. *)») Будет либо «fghij», либо «abcde\nfghij». Как говорили другие, некоторые реализации позволяют вам контролировать, является ли "." будет соответствовать новой строке, предоставив вам выбор.

Использование регулярных выражений на основе строк обычно используется для командной строки, например egrep.

6
задан Hameer Abbasi 3 March 2019 в 10:53
поделиться

2 ответа

Можно выполнить первую часть или требование. Но для этого потребуется вспомогательный класс проверки . MySubClass является потомком типа, MySubClass(0) должен быть классом. Достаточно создать внутренний класс InstanceChecker в MySubClass и поставить __instancecheck__ переопределить их.

Код может быть:

class MySubClass(MySuperClass):
    def __new__(cls, name, bases=None, namespace=None, *args, **kwargs):
        if bases is not None:
            return super().__new__(cls, name, bases, namespace, **kwargs)
        return cls.InstanceChecker(name)

    class InstanceChecker:
        def __init__(self, t):
            self.t = t
        def __instancecheck__(self, instance):
            return isinstance(instance.__class__, MySubClass) and instance.t == self.t            

class MyObject(metaclass=MySubClass):
    def __init__(self, t):
        self.t = t

# Test code:
## Both of these, square brackets work too
assert isinstance(MyObject(0), MySubClass(0))
assert not isinstance(MyObject(0), MySubClass(1))

Кстати, я удалил переопределение __subclasscheck__, потому что t только в атрибуте экземпляра в MyObject

< hr>

В качестве альтернативы, метакласс может автоматически добавить суперкласс в параметре bases. В следующем коде MySuperClass больше не является суперклассом MySubClass, а MyObject:

class MySuperClass():
    pass


class MySubClass(type):
    def __new__(cls, name, bases=None, namespace=None, *args, **kwargs):
        if bases is not None:
            return super().__new__(cls, name, bases + (MySuperClass,), namespace, **kwargs)
        return cls.InstanceChecker(name)
    class InstanceChecker:
        def __init__(self, t):
            self.t = t
        def __instancecheck__(self, instance):
            return isinstance(instance.__class__, MySubClass) and instance.t == self.t

class MyObject(metaclass=MySubClass):
    def __init__(self, t):
        self.t = t

# Test code:
## Both of these, square brackets work too
assert isinstance(MyObject(0), MySubClass(0))
assert not isinstance(MyObject(0), MySubClass(1))

## Ideally
assert isinstance(MyObject(0), MySuperClass)
0
ответ дан Serge Ballesta 3 March 2019 в 10:53
поделиться

Кажется, я нашел решение, и оно намного, намного чище, чем то, которое я изначально имел в виду.

class MyMetaSuper(type):
    pass

class MyObject:
    def __init__(self, t):
        self.t = t

    def __class_getitem__(cls, key):        
        class MyMeta(MyMetaSuper):
            t = key
            def __instancecheck__(self, instance):
                return isinstance(instance, cls) and self.t == instance.t

            def __subclasscheck__(self, subclass):
                return isinstance(subclass, MyMetaSuper) and self.t == subclass.t

        class MyObjectSpecific(MyObject, metaclass=MyMeta):
            pass

        return MyObjectSpecific

# Check for specific condition
assert isinstance(MyObject(0), MyObject[0])
# Make sure isinstance fails when condition fails
assert not isinstance(MyObject(0), MyObject[1])

# Test the generic object
assert isinstance(MyObject(0), MyObject)
0
ответ дан Hameer Abbasi 3 March 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: