Your code looks ok to me, but I made a change in your default function, so that there is no error when op is not available in your dictionary. Also add the function call:
a=10
b=5
def add(a,b):
    return a+b 
def sub(a,b):
    return a-b
def mul(a,b):
    return a*b
def div(a,b):
    return a/b
def default(*args): # a, b are input, to prevent an positional arguments error add *args.
    return "not a valid option"
opt={
   1: add,
   2: sub,
   3: mul,
   4: div
}
op=2
# Call the function:
print(opt.get(op, default)(a,b))
>>> 5
print( opt.get(None, default)(a,b) )
>>> 'not a valid option'
EDIT:
Why the *args part in the function? *args is one method to capture variable for a function which are not defiend:
def test(*args):
    for arg in args:
        print(arg, end=' ') # end=' ' adds an space instead of a new line after print.
test(1, 2, 5)
>>> 1, 2, 3
What happens when a function is called without *args?:
def test():
    print('TEST')
test(1, 2)
>>> TypeError: test() takes 0 positional arguments but 2 were given
You are expecting a function from your dictionary and you are going to add the arguments a and b. Therefore you have to deal with them in each function in the dictionary.
What you also could do is:
def default(a,b):
    # Just ignore a,b
    return 'not valid'
That will also work, but if you want to add more arguments for other functions in the future the advantage of *args is taht it can take as much arguments as you want, there is no maximum.