I'm embedding Python into an application.
MyClass.name is a property of
>>> foo = MyClass()
Should I allow users to do this:
>>> foo.name = 123
>>> foo.name = 123
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: name must be a string
Definitely raise a
TypeError rather than attempting to automatically coerce. Normally I would be conservative about saying that something is "pythonic" or not – it's one of those words that really just means "the speaker thinks that this is good" – but if it means anything at all, it must refer to adhering to the Zen of Python, and in this case, it's dictum 12: "In the face of ambiguity, refuse the temptation to guess."
Right now, you're just looking at integers, but what about floats, or Decimals, or Fractions? Are you using the
str or the
repr of your value? Is the right string value "Decimal('10')" or "10" if you have a
Decimal instance? What about tuples, lists, strings, bytes, arrays, dicts, and all the other built-in types in Python? What about user-defined types that you don't know about yet, and can't ever know about because they're part of a program that hasn't been written yet?
It's unlikely that your library is special enough to have weird, automatic behavior that will confuse people used to Python's conventions. (Dictum 8: "Special cases aren't special enough to break the rules.") However, if this really improves the usability of your library, and you feel you can comfortably answer all of these questions for any arbitrary type that a user might assign, then go ahead and do magical coercion. (Dictum 9: "Although practicality beats purity.") But it's a very rare library indeed that really needs this sort of behavior, and if you do do it, document the heck out of it so that when it does something surprising, your users (or even maybe just yourself!) can go back and read up on the specific rules.
That depends really on what you want to achieve. I think the best solution is to allow any object, that can be coerced to string and then use python properties.
class MyClass(object): def set_name(self, name): self._name = str(name) def get_name(self): return self._name name = propert(get_name, set_name)