Аккуратный способ расширить атрибут класса в подклассах

Казалось бы, ваша лучшая ставка - использовать BroadcastReceiver. Вы можете создать новый BroadcastReceiver, который прослушивает Intent для запуска вашего уведомления и запускает вашу службу следующим образом:

public class MyIntentReceiver extends BroadcastReceiver {    
  @Override 
  public void onReceive(Context _context, Intent _intent) {
    if (_intent.getAction().equals(MY_INTENT)) {
      // TODO Broadcast a notification
      _context.startService(new Intent(_context, MyService.class));
    }
  }    
}

И вы можете зарегистрировать этот IntentReceiver непосредственно в манифесте приложения без необходимости включать его в Activity :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.domain.myapplication">
  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <service android:enabled="true" android:name="MyService"></service>
    <receiver android:enabled="true" android:name="MyIntentReceiver">
      <intent-filter>
        <action android:name="MY_INTENT" />
      </intent-filter>
    </receiver>
  </application>
</manifest> 
16
задан Nadia Alramli 25 May 2009 в 16:48
поделиться

6 ответов

Одним из способов было бы использовать аргументы ключевого слова для указания дополнительных ключей:

Parent.options = dict(
    option1='value1',
    option2='value2',
)

Child.options = dict(Parent.options,
    option2='value2a',
    option3='value3',
)

Если вы хотите получить более привлекательный вид, то с помощью протокола дескриптора вы можете создать прокси-объект, который будет инкапсулировать уважать. (просто проведите владельца .__ mro__ от атрибута owner к методу __get __ (self, instance, owner)). Или, что еще интереснее, переход на территорию, которая, вероятно, не очень хорошая идея, метаклассы / декораторы классов.

8
ответ дан 30 November 2019 в 16:10
поделиться

Семантически эквивалентно вашему коду, но, возможно, более аккуратно:

class Child(Parent):
   Options = dict(Parent.Options,
      option2='value2',
      option3='value3')

Помните, что «жизнь лучше без фигурных скобок», и, явно вызывая dict , вы часто можете избежать фигурных скобок (и дополнительные кавычки вокруг ключей, которые представляют собой постоянные строки, подобные идентификатору).

Подробнее см. http://docs.python.org/library/stdtypes.html#dict - бит ключа - " Если ключ указан как в позиционном аргументе, так и в качестве аргумента ключевого слова, значение, связанное с ключевым словом, сохраняется », т.е. ключевое слово args переопределяет ассоциации значения ключа в позиционном аргументе, как и метод update позволяет вам переопределить их).

21
ответ дан 30 November 2019 в 16:10
поделиться

Поразмыслив, и благодаря предложению @SpliFF, я пришел к следующему:

class Parent(object):
    class Options:
        option1 = 'value1'
        option2 = 'value2'


class Child(Parent):
    class Options(Parent.Options):
        option2 = 'value2'
        option3 = 'value3'

Я все еще открыт для лучших решений.

6
ответ дан 30 November 2019 в 16:10
поделиться

Почему бы просто не использовать атрибуты класса?

class Parent(object):
    option1 = 'value1'
    option2 = 'value2'

class Child(Parent):
    option2 = 'value2'
    option3 = 'value3'
4
ответ дан 30 November 2019 в 16:10
поделиться
class ParentOptions:
  option1 = 'value1'
  option2 = 'value2'

class ChildOptions(ParentOptions):
  option2 = 'value2'
  option3 = 'value3'

class Parent(object):
  options = ParentOptions()

class Child(Parent):
  options = ChildOptions()
2
ответ дан 30 November 2019 в 16:10
поделиться

Вот способ с использованием метакласса

class OptionMeta(type):
    @property
    def options(self):
        result = {}
        for d in self.__mro__[::-1]:
            result.update(getattr(d,'_options',{})) 
        return result

class Parent(object):
    __metaclass__ = OptionMeta
    _options = dict(
        option1='value1',
        option2='value2',
        )

class Child(Parent):
    _options = dict(
        option2='value2a',
        option3='value3',
        )

print Parent.options
print Child.options
2
ответ дан 30 November 2019 в 16:10
поделиться
Другие вопросы по тегам:

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