Определение абстрактных свойств в Python [дубликат]

Да, вы можете и ваш администратор базы данных будет ненавидеть вас, и вы обнаружите, что вы прибиваете ботинки к полу, потому что это вызовет множество операций ввода-вывода и приведет к снижению производительности базы данных по мере очистки кеша.

select column_name from all_tab_columns c, user_all_tables u where c.table_name = u.table_name;

для начала.

Я бы начал с запущенных запросов, используя v$session и v$sqlarea. Это изменяется в зависимости от версии oracle. Это сократит пространство и не ударит все.

31
задан deamon 29 April 2010 в 10:47
поделиться

9 ответов

Для этого у Python есть встроенное исключение, хотя вы не столкнетесь с этим исключением до времени выполнения.

class Base(object):
    @property
    def path(self):
        raise NotImplementedError


class SubClass(Base):
    path = 'blah'
48
ответ дан user 18 August 2018 в 17:19
поделиться
  • 1
    В частности, вы не столкнетесь с исключением до тех пор, пока не будет достигнут attrtibute, и в этом случае вы получили бы AttributeError в любом случае. – Ben James 29 April 2010 в 11:16
  • 2
    Я думаю, что повышение NotImplementedError является более явным и, следовательно, вероятно лучше, чем оставить его в AttributeError. – blokeley 29 April 2010 в 13:48
  • 3
    Также вы можете добавить сообщение типа & quot; Невозможно создать экземпляр абстрактного класса Base & quot; когда вы сами создаете исключение. – Bastien Léonard 29 April 2010 в 15:23
  • 4
  • 5
    Не то, что это работает, только если path устанавливается непосредственно на SubClass. Учитывая экземпляр sc = SubClass(), если вы пытаетесь установить sc.path = 'blah' или иметь метод, который содержит что-то вроде self.path = 'blah' без указания path непосредственно на SubClass, вы получите AttributeError: can't set attribute. – erik 31 March 2015 в 16:59

Реализация Python3.6 может выглядеть так:

In [20]: class X:
    ...:     def __init_subclass__(cls):
    ...:         if not hasattr(cls, 'required'):
    ...:             raise NotImplementedError

In [21]: class Y(X):
    ...:     required =5
    ...:     

In [22]: Y()
Out[22]: <__main__.Y at 0x7f08408c9a20>
1
ответ дан Artem Zhukov 18 August 2018 в 17:19
поделиться

В ответе Бастиана Леонарда упоминается модуль абстрактного базового класса, и ответ Брендана Абеля касается не реализованных атрибутов, вызывающих ошибки. Чтобы гарантировать, что класс не реализован вне модуля, вы можете префикс базового имени с подчеркиванием, которое обозначает его как закрытое для модуля (т. Е. Оно не импортируется).

i.e.

class _Controller(object):
    path = '' # There are better ways to declare attributes - see other answers

class MyController(_Controller):
    path = '/Home'
5
ответ дан Brendan 18 August 2018 в 17:19
поделиться
  • 1
    возможно ли повысить некоторую ошибку, если подкласс не переопределяет атрибут? Это было бы легко для методов, но как насчет атрибутов? – Mario F 29 April 2010 в 11:08
  • 2
    Не лучше ли оставить объявление пути в классе _Controller? Duck Typing не вступает в силу, если уже есть (недопустимое) значение. В противном случае в какой-то момент, когда мне нужно определить поле path, которое будет определено, ошибки не будет, потому что уже есть значение. – deamon 29 April 2010 в 11:25
  • 3
    @Mario - да, ответ Брендана Абеля дает хороший способ сделать это – Brendan 29 April 2010 в 14:07
  • 4
    Пожалуйста, уточните: как модуль abc помогает в этом контексте? – guettli 16 June 2016 в 14:32
class AbstractStuff:
    @property
    @abc.abstractmethod
    def some_property(self):
        pass

По состоянию на 3.3 abc.abstractproperty, я считаю, что это не рекомендуется.

0
ответ дан grisaitis 18 August 2018 в 17:19
поделиться

Ваш базовый класс может реализовать метод __new__, который проверяет атрибут класса:

class Controller(object):
    def __new__(cls, *args, **kargs):
        if not hasattr(cls,'path'): 
            raise NotImplementedError("'Controller' subclasses should have a 'path' attribute")
        return object.__new__(cls,*args,**kargs)

class C1(Controller):
    path = 42

class C2(Controller):
    pass


c1 = C1() 
# ok

c2 = C2()  
# NotImplementedError: 'Controller' subclasses should have a 'path' attribute

Таким образом, ошибка возникает при создании экземпляра

3
ответ дан Juh_ 18 August 2018 в 17:19
поделиться
  • 1
    интересно, это не работает, если вам нужно использовать def __init __ (self). – szeitlin 6 October 2015 в 20:30

Вы можете создать атрибут в базовом классе abc.ABC с таким значением, как NotImplemented , чтобы, если атрибут не переопределяется, а затем используется, ошибка отображается во время выполнения.

Следующий код использует подсказку типа PEP 484 , чтобы помочь PyCharm правильно статически проанализировать тип атрибута path.

import abc


class Controller(abc.ABC):
    path = NotImplemented  # type: str


class MyController(Controller):
    path = '/home'
5
ответ дан phoenix 18 August 2018 в 17:19
поделиться

Python 2.7

Для этого есть декоратор @abstractproperty :

from abc import ABCMeta, abstractmethod, abstractproperty


class A:
    __metaclass__ = ABCMeta

    def __init__(self):
        # ...
        pass

    @abstractproperty
    def a(self):
        pass

    @abstractmethod
    def b(self):
        pass


class B(A):
    a = 1

    def b(self):
        pass

Невозможно объявить a или b в производный класс B поднимет значение TypeError, например:

TypeError: не может создать абстрактный класс B с абстрактными методами a

Python 3.3 +

Из документации :

Устаревший с версии 3.3: теперь можно использовать property, property.getter(), property.setter() и property.deleter() с abstractmethod(), что делает этот декоратор избыточным.

Вышеприведенный пример является следующим:

from abc import ABCMeta, abstractmethod


class A(metaclass=ABCMeta):
    def __init__(self):
        # ...
        pass

    @property
    @abstractmethod
    def a(self):
        pass

    @abstractmethod
    def b(self):
        pass


class B(A):
    a = 1

    def b(self):
        pass
33
ответ дан Wtower 18 August 2018 в 17:19
поделиться
5
ответ дан Brendan 7 September 2018 в 01:54
поделиться
5
ответ дан Brendan 30 October 2018 в 06:12
поделиться
Другие вопросы по тегам:

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