"staticmethod" ve "abc.abstractmethod": Karışacak mı?


106

Python uygulamamda hem a hem de staticmethodan olan bir yöntem yapmak istiyorum abc.abstractmethod. Bunu nasıl yaparım?

Her iki dekoratörü de uygulamayı denedim ama işe yaramadı. Bunu yaparsam:

import abc

class C(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    @staticmethod    
    def my_function(): pass

Bir istisna yaşıyorum * ve bunu yaparsam:

class C(object):
    __metaclass__ = abc.ABCMeta

    @staticmethod    
    @abc.abstractmethod
    def my_function(): pass

Soyut yöntem uygulanmaz.

Soyut bir statik yöntemi nasıl yapabilirim?

*İstisna:

File "c:\Python26\Lib\abc.py", line 29, in abstractmethod
 funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'

5
Lütfen kabul ettiğiniz cevabı güncelleyin.
Neil G

Yanıtlar:


34
class abstractstatic(staticmethod):
    __slots__ = ()
    def __init__(self, function):
        super(abstractstatic, self).__init__(function)
        function.__isabstractmethod__ = True
    __isabstractmethod__ = True

class A(object):
    __metaclass__ = abc.ABCMeta
    @abstractstatic
    def test():
        print 5

7
İyi oynadınız efendim ya da bayan :-) En üstte kaldınız import abc; yanı sıra A. örneğini gösteren bir alt sınıf (ör. class B(A):\n @staticmethod\n def test():\n print 10\n)
Dan Breslau

1
Kodu alt sınıflandırma ile düzgün çalışacak şekilde güncelledim. A.test ayrıca __isabstractmethod__özniteliğe sahip olmalıdır .
Rosh Oxymoron

3
Meli abstractstaticiçin yukarı eklenebilir abc.py?
nnyby

3
abstractstaticmethod Sürüm 3.3'ten beri kullanımdan kaldırıldı: Artık bu dekoratörü gereksiz kılarak abstractmethod () ile staticmethod kullanmak mümkün. bağlantı
irakli khitarishvili

1
@iraklikhitarishvili Yine de, bu alt sınıfın yöntemini statik olmaya zorlamaz! Statik yöntem dekoratörünü kopyalamalısın ... Bunun etrafında bir yol yok mu?
étale-cohomology

199

Python 3.3 ile başlayarak , birleştirmek mümkündür @staticmethod ve @abstractmethodbu nedenle diğer önerilerin hiçbiri artık gerekli değildir:

@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):

32
@staticmethodİlk olarak koymanız gerektiğini unutmayın, yoksa alacaksınızAttributeError: attribute '__isabstractmethod__' of 'staticmethod' objects is not writable
Marco Sulla

3
Aynısı@property
zezollo

11
Kabul edilen cevap bu olsaydı gerçekten yardımcı olurdu!
Keerthana Prabhakaran

Tam olarak aradığım şey. Teşekkürler!
shanu khera

13

Bunu yapacak:

  >>> import abc
  >>> abstractstaticmethod = abc.abstractmethod
  >>>
  >>> class A(object):
  ...     __metaclass__ = abc.ABCMeta
  ...     @abstractstaticmethod
  ...     def themethod():
  ...          pass
  ... 
  >>> a = A()
  >>> Traceback (most recent call last):
  File "asm.py", line 16, in <module>
    a = A()
  TypeError: Can't instantiate abstract class A with abstract methods test

"Eh? Sadece @abstractmethod" adını değiştiriyorsunuz ve bu tamamen doğru. Çünkü yukarıdakilerin herhangi bir alt sınıfının @staticmethod dekoratörünü içermesi gerekecek. Kodu okurken dokümantasyon haricinde burada buna ihtiyacınız yok. Bir alt sınıfın şöyle görünmesi gerekir:

  >>> class B(A):
  ...     @staticmethod
  ...     def themethod():
  ...         print "Do whatevs"

Sizi bu yöntemi statik bir yöntem yapmaya zorlayacak bir işleve sahip olmak için, bunu kontrol etmek ve zorlamak için ABCmeta'yı alt sınıflara ayırmanız gerekir. Gerçek bir geri dönüşü olmayan çok fazla iş. (Biri @staticmethod dekoratörünü unutursa, yine de net bir hata alır, statik yöntemlerden bahsetmez.

Yani aslında bu da işe yarıyor:

  >>> import abc
  >>>
  >>> class A(object):
  ...     __metaclass__ = abc.ABCMeta
  ...     @abc.abstractmethod
  ...     def themethod():
  ...         """Subclasses must implement this as a @staticmethod"""
  ...          pass

Güncelleme - Bunu açıklamanın başka bir yolu:

Bir yöntemin statik olduğu, nasıl çağrıldığını kontrol eder. Soyut bir yöntem asla çağrılmaz. Soyut statik yöntem bu nedenle, dokümantasyon amaçları dışında oldukça anlamsız bir kavramdır.


4

Bu, Python 2.X'te şu anda mümkün değildir, bu sadece yöntemi soyut veya statik olmaya zorlar, ikisini birden değil.

Python 3.2+ yılında yeni dekoratör abc.abstractclassmethodve abc.abstractstaticmethodsoyut ve statik veya soyut ve sınıf yöntemi olma onların uygulanmasını birleştirmek için eklenmiştir.

Python Sayı 5867'ye bakın


11
Python 3.2 yeni, iken abstractclassmethodve abstractstaticmethodhızla sıra sıra, Python 3.3 kullanımdan kaldırılmış edildi abstractproperty. docs.python.org/3/library/abc.html
glarrain

4
Bilginize: bugs.python.org/issue11610 , sınırlamayı ve bunu yapmanın yeni yolunu
açıklıyor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.