Python oct() Function: Syntax and Behavior
python oct function: Learn how Python's oct() converts integers to octal strings, what inputs it accepts, how the 0o prefix works, and when to use format() instead.
python oct function requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
The oct() built-in converts an integer to its octal representation as a string. The result always starts with the 0o prefix, matching the literal syntax Python uses for octal numbers.
>>> oct(8) '0o10' >>> oct(64) '0o100' >>> oct(255) '0o377'
The function takes a single argument. For a standard int, the result is the shortest octal string that represents the value, prefixed with 0o. Negative numbers keep their sign:
>>> oct(-8) '-0o10'
Accepted Input Types
oct() accepts any object that implements the __index__() method. This includes int and bool, as well as custom classes that define __index__.
class Port: def __init__(self, value): self.value = value def __index__(self): return self.value oct(Port(16)) # '0o20'
bool is a subclass of int, so oct(True) returns '0o1' and oct(False) returns '0o0'.
Objects that do not implement __index__ raise TypeError. Floats, strings, and lists are rejected even when they hold integer-like values:
oct(8.0) # TypeError: 'float' object cannot be interpreted as an integer oct("8") # TypeError: 'str' object cannot be interpreted as an integer
The 0o Prefix and Round-Tripping
The 0o prefix is significant. It makes the output a valid Python literal, so the string can be passed directly to int() with base 0 or evaluated as source code.
s = oct(64) # '0o100' int(s, 0) # 64
Without the prefix, int(s, 8) would also work, but the prefix makes the representation self-describing. This matters when octal strings are stored in configuration files or logs and later parsed without knowing the intended base.
Formatting Octal Without the Prefix
When the 0o prefix is not wanted, format() or an f-string with the o type specifier produces the bare digits:
format(64, 'o') # '100' f"{64:o}" # '100'
This is the standard way to get octal digits for file permission masks or bit-field output where the prefix would be noise. The format() approach also accepts width and zero-padding options:
format(8, '04o') # '0010'
Common Use Cases
Octal representation appears most often in Unix file permission work and in bit manipulation where groups of three bits map naturally to octal digits.
For a permission mask:
mask = 0o755 oct(mask) # '0o755'
For bit-field inspection, octal groups each three bits into one digit. Given an integer representing flags, the octal form makes the individual bit groups readable:
flags = 0b101_110_001 oct(flags) # '0o561'
The 0o prefix in the output also mirrors the literal syntax, which reduces confusion when comparing values.
Edge Cases and Common Mistakes
Passing a float that happens to be integral raises TypeError. This is a frequent surprise for developers coming from languages where numeric conversion is more permissive.
Another mistake is assuming oct() accepts a base argument. It does not. The function signature is oct(number) only. To parse a string in a specific base, use int(string, base).
For very large integers, oct() handles arbitrary precision correctly:
oct(2**100) # '0o1267650600228229401496703205376'
The output length grows linearly with the number of bits, and there is no overflow behavior to handle.
Performance and Compatibility Considerations
oct() is a built-in implemented in C. For a single conversion the cost is negligible. When converting many integers in a loop, the string allocation dominates, and oct() performs comparably to format(x, 'o'). There is no meaningful performance reason to prefer one over the other.
Python 3 requires the 0o prefix on octal literals; the older 0-prefixed literal form from Python 2 was removed. The oct() function's output has always used the 0o prefix in Python 3, which keeps the round-trip behavior consistent.
Custom classes that define __index__ must return an int. Returning a float or str raises TypeError, so the contract is strict.
When Not to Use oct()
If the goal is human-readable output for a permissions string like rwxr-xr-x, converting to octal digits is only an intermediate step. A symbolic form is usually clearer:
def symbolic(mask): bits = [(0o400, 'r'), (0o200, 'w'), (0o100, 'x'), (0o040, 'r'), (0o020, 'w'), (0o010, 'x'), (0o004, 'r'), (0o002, 'w'), (0o001, 'x')] return ''.join(ch if mask & b else '-' for b, ch in bits) symbolic(0o755) # 'rwxr-xr-x'
For bit manipulation, bin() is often more direct when the grouping is by single bits rather than triples. Choose the representation that matches how the data is consumed downstream.