I know the logic behind implementing my own but there a built-in Python function that takes an integer and returns True if it is written in binary form?
For example, is_binary(0b1010) would return True but is_binary(12) would return False.
No, since 0b1010 is converted to the same representation as 10 by the 'compiler', which of course happens long before it is being passed to the function.
We can confirm this by investigating the produced code.
import dis
def binary():
a = 0b1010
def base_10():
a = 10
dis.dis(binary)
print()
dis.dis(base_10)
Outputs
17 0 LOAD_CONST 1 (10) # <-- Same represntation here
2 STORE_FAST 0 (a)
4 LOAD_CONST 0 (None)
6 RETURN_VALUE
20 0 LOAD_CONST 1 (10) # <-- as here
2 STORE_FAST 0 (a)
4 LOAD_CONST 0 (None)
6 RETURN_VALUE
If it is that important for you, you will have to implement some sort of AST parser which I assume will be able to grab the binary literal before it is converted.
10 is "normal" somehow and 0b1010 isn't. Both 10 and 0b1010 express the exact same value, which is just an integer and doesn't have any inherent base. The default repr gives decimal, but the int isn't inherently decimal. (The CPython implementation happens to represent integers in either base 2^15 or base 2^30, but this is an implementation detail with no impact on int semantics.)0b1010 is as normal as 10 is :) I'll try to express that better than just using quotes.If you really need such functionality and don't care for performance, you could tokenize the source:
scenox@Mac ~ % echo 'print(0b1010)' | python3 -m tokenize
1,0-1,5: NAME 'print'
1,5-1,6: OP '('
1,6-1,12: NUMBER '0b1010'
1,12-1,13: OP ')'
1,13-1,14: NEWLINE '\n'
2,0-2,0: ENDMARKER ''
So you can do something like that:
g = tokenize(BytesIO(somestring.encode('utf-8')).readline) # tokenize the string
for toknum, tokval, _, _, _ in g:
if toknum == NUMBER and tokval.startswith('0b'):
...
0b1010and10are indistinguishable.0b1010and10anymore.0b1010becomes10long before it even passed to the so-calledis_binaryfunction