Là f = 1..__truediv__
gì
f
là một phương pháp đặc biệt ràng buộc trên một float với giá trị là một. Đặc biệt,
1.0 / x
trong Python 3, gọi:
(1.0).__truediv__(x)
Chứng cớ:
class Float(float):
def __truediv__(self, other):
print('__truediv__ called')
return super(Float, self).__truediv__(other)
và:
>>> one = Float(1)
>>> one/2
__truediv__ called
0.5
Nếu chúng ta làm:
f = one.__truediv__
Chúng tôi giữ lại một tên ràng buộc với phương thức ràng buộc đó
>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333
Nếu chúng ta đang thực hiện tra cứu rải rác đó trong một vòng lặp chặt chẽ, điều này có thể tiết kiệm một ít thời gian.
Phân tích cú pháp cây cú pháp trừu tượng (AST)
Chúng ta có thể thấy rằng phân tích AST cho biểu thức cho chúng ta biết rằng chúng ta đang nhận được __truediv__
thuộc tính trên số dấu phẩy động , 1.0
:
>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"
Bạn có thể nhận được chức năng kết quả tương tự từ:
f = float(1).__truediv__
Hoặc là
f = (1.0).__truediv__
Khấu trừ
Chúng tôi cũng có thể đến đó bằng cách khấu trừ.
Hãy xây dựng nó lên.
1 bởi chính nó là một int
:
>>> 1
1
>>> type(1)
<type 'int'>
1 với một khoảng thời gian sau khi nó là một float:
>>> 1.
1.0
>>> type(1.)
<type 'float'>
Dấu chấm tiếp theo tự nó sẽ là một SyntaxError, nhưng nó bắt đầu một tra cứu chấm trên trường hợp của float:
>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>
Không ai khác đã đề cập đến điều này - Đây hiện là một "phương thức ràng buộc" trên float , 1.0
:
>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331
Chúng ta có thể thực hiện cùng chức năng dễ đọc hơn nhiều:
>>> def divide_one_by(x):
... return 1.0/x
...
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331
Hiệu suất
Nhược điểm của divide_one_by
hàm là nó yêu cầu một khung stack Python khác, làm cho nó chậm hơn một chút so với phương thức ràng buộc:
>>> 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]
Tất nhiên, nếu bạn chỉ có thể sử dụng chữ đơn giản, điều đó thậm chí còn nhanh hơn:
>>> def f_3():
... for x in range(1, 11):
... 1.0/x
...
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]
(1).__truediv__
không thực sự giống1..__truediv__
như các cuộc gọi trướcint.__truediv__
trong khi cuộc gọi sau thực hiệnfloat.__truediv__
. Ngoài ra, bạn cũng có thể sử dụng1 .__truediv__
(có dấu cách) `