나는 최근에 걸쳐왔 구문을 나는 본 적이 없기 때 나는 배운 python 도에서 가장습서,..
기법,그것은 다음과 같이 나타납니다.
f = 1..__truediv__ # or 1..__div__ for python 2
print(f(8)) # prints 0.125
나는 그것은 정확히 동일(제외하고는's,더 이상의 코스):
f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8
그러나 나의 질문은:
그것은 어떻게 할 수 있는? 이것이 실제로 의미하는 바는 무엇을 가진 두 개의 점? *당신은 그것을 사용하는 방법에는 더 복잡한 문이(가능하면)?
이것은 아마도 나를 저장 많은 라인의 코드를 미래에...:)
당신은 플로트리터럴 없이 뒤로는,당신은에 액세스
truediv`방법이다. It's 지 않은 운영자는 그 자체로 처음 도입부 부동의 값이고,두 번째는 점을 운영자에 액세스하는 개체의 특성 및 방법입니다.
도달할 수 있는 동일한 지점을 수행하여 다음과 같습니다.
>>> f = 1.
>>> f
1.0
>>> f.__floordiv__
<method-wrapper '__floordiv__' of float object at 0x7f9fb4dc1a20>
또 다른 예
>>> 1..__add__(2.)
3.0
여기서 우리는 추가 1.0 2.0 는 분명히 수익률 3.0.
이 질문은 이미 충분히 답변(예:@폴 루니s 답변)하지만 그것이's 도 가능하의 정확성을 검증하기 위해 이러한 답변이 있습니다.
게 정리해 기존의 답변:는..
은 단순한 구문 요소!
할 수 있는 방법을 확인의 소스 코드가"토큰화". 이러한 토큰을 나타내는 방법 코드 해석됩니다:
>>> from tokenize import tokenize
>>> from io import BytesIO
>>> s = "1..__truediv__"
>>> list(tokenize(BytesIO(s.encode('utf-8')).readline))
[...
TokenInfo(type=2 (NUMBER), string='1.', start=(1, 0), end=(1, 2), line='1..__truediv__'),
TokenInfo(type=53 (OP), string='.', start=(1, 2), end=(1, 3), line='1..__truediv__'),
TokenInfo(type=1 (NAME), string='__truediv__', start=(1, 3), end=(1, 14), line='1..__truediv__'),
...]
그래서 이 문자열1.
해석됩니다 숫자로,두 번째.
is an OP(연산자,이 경우,"얻을 속성"운영자)와__truediv__는
메서드 이름입니다. 그래서 이것은 그냥에 액세스하는__truediv__
방식의 플로트1.0
.
또 다른 방법을 볼 생성되는 바이트 코드를`dis'assemble니다. 이것이 실제 지침을 때 수행되는 몇 가지 코드가 실행됩니다:
>>> import dis
>>> def f():
... return 1..__truediv__
>>> dis.dis(f)
4 0 LOAD_CONST 1 (1.0)
3 LOAD_ATTR 0 (__truediv__)
6 RETURN_VALUE
기본적으로 말한 동일합니다. 그것을 로드하는 특성__truediv__
일정한1.0
.
귀하의 질문에 대 한
그리고 당신은 그것을 사용하는 방법에는 더 복잡한 문이(가능하면)?
비록 그것이's 한 가능한 코드를 작성하지 마십시오 좋아하는 간단하기 때문에,그것이's 무엇인지 명확하지 않는 코드입니다. 시기 바랍't 에서 사용하는 더 복잡한 문입니다. 나도는 당신이 안't 에 그것을 사용하므"simple"문서,적어도 당신이 해야 괄호를 사용하여 별도의 지침:
f = (1.).__truediv__
이 될 것 이라고 확실히 더 많은 읽을 수 있지만 뭔가의 라인을 따라:
from functools import partial
from operator import truediv
f = partial(truediv, 1.0)
더 나은 것!
이 방법을 사용하여부분
또한 유지python's 데이터 모델(1..__truediv__
접근 방식을 하지 않습니다!) 할 수 있는 시연으로 이 작은 조각:
>>> f1 = 1..__truediv__
>>> f2 = partial(truediv, 1.)
>>> f2(1+2j) # reciprocal of complex number - works
(0.2-0.4j)
>>> f2('a') # reciprocal of string should raise an exception
TypeError: unsupported operand type(s) for /: 'float' and 'str'
>>> f1(1+2j) # reciprocal of complex number - works but gives an unexpected result
NotImplemented
>>> f1('a') # reciprocal of string should raise an exception but it doesn't
NotImplemented
이 때문에1. /(1+2j)
평가되지 않은습니다.__truediv__
하지만복잡합니다.__rtruediv__
-연산자입니다.truediv
게 반대의 작업이라면 정상적인 작업이 반환NotImplemented
그러나 너는't 가 이러한 대체가 작동할 때에는__truediv__
이 직접 있습니다. 의 손실이"기대되는 행동 양식"은 주된 이유(일반적으로)안't 마법을 사용하는 방법이 직접 있습니다.
두 점을 함께 수 있습니다 처음에는 어색:
f = 1..__truediv__ # or 1..__div__ for python 2
하지만 그것을 쓰는 것과 같은:
f = 1.0.__truediv__ # or 1.0.__div__ for python 2
기 때문에플로트
리터럴 쓸 수 있는 세 가지 형태:
normal_float = 1.0
short_float = 1. # == 1.0
prefixed_float = .1 # == 0.1
무엇입 f=1..truediv`?
f
는밖에 없는 특별한 방법에 플로트와 가치의 하나입니다. 특히,
1.0 / x
Python3 호출:
(1.0).__truediv__(x)
증거들이 있습니다.:
class Float(float):
def __truediv__(self, other):
print('__truediv__ called')
return super(Float, self).__truediv__(other)
고:
>>> one = Float(1)
>>> one/2
__truediv__ called
0.5
우리가 할 경우:
f = one.__truediv__
우리는지 이름에 바인딩하는 방법밖에 없
>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333
우리가 하고 있었다는 점에서 조회 단단한 루프로,이를 저장할 수 있는 시간이 좀 있습니다.
우리가 볼 수 있는 구문 분석 AST 표현에 대 한 우리에게는 우리가 얻고 있는__truediv__
특성에 floating point number,1.0
:
>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"
을 얻을 수 있습 같은 결과에서 기능:
f = float(1).__truediv__
나
f = (1.0).__truediv__
우리가 받을 수 있어가 공제입니다.
Let's 그것을 구축합니다.
1 에 의해 자체가int
:
>>> 1
1
>>> type(1)
<type 'int'>
1 과 후 부동:
>>> 1.
1.0
>>> type(1.)
<type 'float'>
다음 점은 그 자체가 될 것입 SyntaxError 지만,그 시작이 점회의 인스턴스에서 떠:
>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>
지 않 이-이것은 지금"바인딩 방법"에 float,1.0
:
>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331
우리가 할 수 있는 동일한 기능을 훨씬 더 readably:
>>> def divide_one_by(x):
... return 1.0/x
...
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331
의 단점은divide_one_by
기능이 필요하다는 것이다 다른 Python 스택 구조 만들기,그것은 다소 느린 것보다 바인딩 방법:
>>> 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]
물론 당신은 사용할 수 있습니다 보통 리터럴는's 이 더 빨리:
>>> def f_3():
... for x in range(1, 11):
... 1.0/x
...
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]