Nedir f = 1..__truediv__
?
f
değeri bir şamandıra üzerinde bağlı özel bir yöntemdir. özellikle,
1.0 / x
Python 3'te:
(1.0).__truediv__(x)
Kanıt:
class Float(float):
def __truediv__(self, other):
print('__truediv__ called')
return super(Float, self).__truediv__(other)
ve:
>>> one = Float(1)
>>> one/2
__truediv__ called
0.5
Eğer yaparsak:
f = one.__truediv__
Bu bağlı yönteme bağlı bir ad tutuyoruz
>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333
Eğer o noktalı aramayı sıkı bir döngü içinde yapsaydık, bu biraz zaman kazandırabilirdi.
Soyut Sözdizimi Ağacının (AST) Ayrıştırılması
İfade için AST'yi ayrıştırmanın bize __truediv__
kayan nokta sayısı niteliğini aldığımızı söylediğini görebiliriz 1.0
:
>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"
Aynı sonuç fonksiyonunu şuradan alabilirsiniz:
f = float(1).__truediv__
Veya
f = (1.0).__truediv__
kesinti
Ayrıca oraya kesinti ile ulaşabiliriz.
Hadi inşa edelim.
1 tek başına int
:
>>> 1
1
>>> type(1)
<type 'int'>
1 float olduktan sonraki bir süre ile:
>>> 1.
1.0
>>> type(1.)
<type 'float'>
Sonraki nokta tek başına bir SyntaxError olur, ancak kayan nokta örneğinde noktalı bir arama başlatır:
>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>
Başka hiç kimse bu sözü var - Bu artık bir olduğunu "bağımlı yöntem" , şamandıra üzerinde 1.0
:
>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331
Aynı işlevi çok daha okunaklı bir şekilde başarabiliriz:
>>> def divide_one_by(x):
... return 1.0/x
...
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331
Verim
divide_one_by
İşlevin dezavantajı, başka bir Python yığın çerçevesi gerektirmesi ve onu bağlı yöntemden biraz daha yavaş hale getirmesidir:
>>> def f_1():
... for x in range(1, 11):
... f(x)
...
>>> def f_2():
... for x in range(1, 11):
... divide_one_by(x)
...
>>> timeit.repeat(f_1)
[2.5495760687176485, 2.5585621018805469, 2.5411816588331888]
>>> timeit.repeat(f_2)
[3.479687248616699, 3.46196088706062, 3.473726342237768]
Tabii ki, sadece düz değişmezleri kullanabiliyorsanız, bu daha da hızlıdır:
>>> def f_3():
... for x in range(1, 11):
... 1.0/x
...
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]
(1).__truediv__
gerçekten aynı değildir . Alternatif olarak, (boşluklu) kullanabilirsiniz1..__truediv__
int.__truediv__
float.__truediv__
1 .__truediv__