2016-11-03 44 views
5

ben yapmak istiyorum:__rmod__ kullanarak str'nin% davranışının üzerine yazmak mümkün mü?

yapmak için yeterli kolaydır
x %doSomething% y 

bir str olan x durumlar dışında herhangi bir x ve herhangi y (aşağıdaki kodu bakınız).

herhangi bir yolu var mı (mesela özel bir yöntemi ekleyerek veya belirli bir hata yükselterek) (benzer şekilde% 1 doSomthing bir TypeError ile başarısız nasıl) başarısız biçimlendirme eski tarz dize neden ve doSomething tanımlanan __rmod__ yöntemi dönmek nesne?

class BinaryMessage(object): 
    def __init__(self, fn): 
    self._fn = fn 
    def __rmod__(self, LHS): 
    return BinaryMessagePartial(self._fn, LHS) 

class BinaryMessagePartial(object): 
    def __init__(self, fn, LHS): 
    self._fn = fn 
    self._LHS = LHS 
    def __mod__(self, RHS): 
    return self._fn(self._LHS, RHS) 

def _doSomething(a , b): 
    return a + b 

doSomething = BinaryMessage(_doSomething) 

result = 5 %doSomething% 6 
assert result == 11 
+2

Netleştirmek için: "foo"% doSomething% "bar" '' '' foobar '' dönmek istiyor musunuz? Bunun imkansız olduğuna inanıyorum çünkü str .__ mod__ '' NotImplemented' döndürme yerine 'TypeError'ı yükseltir. – L3viathan

+0

@MartijnPieters Cevabınız ile çalışmadığını görmüyorum. Soruda olduğu gibi tamsayılar vb. Için çalışır, ancak "foo"% doSomething% "bar", aynı TypeError'u yükseltir. – L3viathan

+0

@ L3viathan: Hayır, burada biraz ileriye gidiyordum. Bu benim görüşüme göre Python'da bir hatadır. –

cevap

7

Not: Python 2.7 için yamalar sunulan ve 3.5 ve üstü. Bunlar, OP örneğinin artık beklendiği gibi çalıştığı 2.7.14, 3.5.4, 3.6.1 ve 3.7'nin bir parçasıydı ve bir kısmı. Daha eski versiyonlar için aşağıya bakın.


Maalesef, bu şu anda Python'da mümkün değildir. davranış değerlendirme döngü içinde kodlanma: (PyUnicode Python str türüdür Python 3.5 source code itibaren)

TARGET(BINARY_MODULO) { 
    PyObject *divisor = POP(); 
    PyObject *dividend = TOP(); 
    PyObject *res = PyUnicode_CheckExact(dividend) ? 
     PyUnicode_Format(dividend, divisor) : 
     PyNumber_Remainder(dividend, divisor); 

.

için size LHS.__mod__ yöntemi önleyebilirsiniz her tip sağ işlenen bir alt sınıfı kullanılarak çağrılacak Bunun nedeni, talihsiz;

Not: sağ işlenen tip sol tarafındaki terimin en türde bir alt sınıfıdır ve bu alt sınıf çalışması için yansıyan yöntem sağlar, bu yöntem, sol işlenen dışı yansıyan önce adı verilecek documentation dan yöntem. Bu davranış, alt sınıfların atalarının işlemlerini geçersiz kılmasına izin verir.

Bu

tüm RHS türleri (gerçek str.__mod__ method sadece RHS için str nesneleri kabul eder, ancak bu durumda çağrılmaz) kabul edilir, str % other asla NotImplemented döndürür burada tek seçenek olurdu.

Bunu Python'da bir hata olarak görüyorum, issue #28598.

+0

Thx. Kesin bir cevaba sahip olmak çok güzel. – DangerMouse

+0

Başlangıçta sorunu işaret etmek için L3viathan'a ve kazma işlemi yapmak ve bir hata izini başlatmak için MartijnPieters'a gitmek için Thx to L3viathan. Seçtiğim geçici çözümüm __mul__' ve '__rmul__' kullanmaktır, dolayısıyla' result = 4 * plus * 5' – DangerMouse