One very simple thing that Io gets right is the unification of instance variables and methods as slots. It lets you override behavior with little friction:
Person := Object clone do(
name ::= nil
greeting := method(
"Hello I'm " .. name
)
)
bob := Person clone setName("Bob") greeting
# => I'm Bob
bill := Person clone
bill greeting := "Yo"
bill greeting
# => Yo
Notice that you use bob.greeting() but bill.greeting (without the parentheses), while Io uses the same syntax in both cases. Whether this is good or bad is mostly a matter of preference, I think...
Of course, this implies that Io would need a separate construct to get the value of a slot (e.g. bob getSlot("greeting")), while in Python you'd just use bob.greeting no matter whether greeting is callable or not.
Your code isn't general. You have to change the interface. In Io is there just one interface (send a message). If the slot identified by the message send is activatable (a method), then it is activated, otherwise it is just returned.