I want to write a class, an instance of which should be usable as an argument of os.mkdir(). Is there a magic method, which I could add to my class, so that this would work? The following implementation with __unicode__():
main.py:
import os
class MyClass(object):
def __init__(self, string):
self.__string = string
def __unicode__(self):
return unicode(self.__string)
obj = MyClass("/tmp/dir")
print unicode(obj)
os.mkdir(obj)
leads to the following error:
/tmp/dir
Traceback (most recent call last):
File "main.py", line 11, in <module>
os.mkdir(obj)
TypeError: coercing to Unicode: need string or buffer, MyClass found
I want to use instances of MyClass in contexts where otherwise a str or unicode is expected. E. g. in order to make "abc" + MyClass("def") work, I can implement the __radd__() magic method in MyClass.
Edited: New code example to explain my intention (MyClass from above corresponds to StringRef below):
import os
class StringRef(object):
def __init__(self, string):
self.__string = string
def set_value(self, value):
self.__string = value
def __str__(self):
return str(self.__string)
def __repr__(self):
return repr(self.__string)
def __unicode__(self):
return unicode(self.__string)
def __add__(self, other):
return self.__string + other
def __radd__(self, other):
return other + self.__string
class SomeClass(object):
def __init__(self, directory):
self.__directory = directory
def use_dir1(self):
print "directory: %s" % self.__directory
def use_dir2(self):
print "subdirectory:", self.__directory + "/subdir"
def use_dir3(self):
os.mkdir(self.__directory)
os.rmdir(self.__directory)
print "* old *"
directory = "/tmp/dir1"
obj = SomeClass(directory) # more objects can be created like this
obj.use_dir1()
directory = "/tmp/dir2" # has no effect on the created objects
obj.use_dir1()
directory = "/tmp/dir1"
obj = SomeClass(directory)
obj.use_dir2()
directory = "/tmp/dir2"
obj.use_dir2()
directory = "/tmp/dir1"
obj = SomeClass(directory)
obj.use_dir3()
directory = "/tmp/dir2"
obj.use_dir3()
print "* new *"
directory = StringRef("/tmp/dir1")
obj = SomeClass(directory) # more objects can be created like this
obj.use_dir1()
directory.set_value("/tmp/dir2") # has effect on all created objects
obj.use_dir1()
directory = StringRef("/tmp/dir1")
obj = SomeClass(directory)
obj.use_dir2()
directory.set_value("/tmp/dir2")
obj.use_dir2()
directory = StringRef("/tmp/dir1")
obj = SomeClass(directory)
obj.use_dir3()
directory.set_value("/tmp/dir2")
obj.use_dir3()
Output:
* old *
directory: /tmp/dir1
directory: /tmp/dir1
subdirectory: /tmp/dir1/subdir
subdirectory: /tmp/dir1/subdir
* new *
directory: /tmp/dir1
directory: /tmp/dir2
subdirectory: /tmp/dir1/subdir
subdirectory: /tmp/dir2/subdir
Traceback (most recent call last):
File "main.py", line 65, in <module>
obj.use_dir3()
File "main.py", line 27, in use_dir3
os.mkdir(self.__directory)
TypeError: coercing to Unicode: need string or buffer, StringRef found
2nd Edit: StringRef(unicode) avoids TypeError but does not create /tmp/dir2:
import os
class StringRef(unicode):
def __init__(self, string):
self.__string = string
def set_value(self, value):
self.__string = value
def __str__(self):
return str(self.__string)
def __repr__(self):
return repr(self.__string)
def __unicode__(self):
return unicode(self.__string)
def __add__(self, other):
return self.__string + other
def __radd__(self, other):
return other + self.__string
class SomeClass(object):
def __init__(self, directory):
self.__directory = directory
def use_directory(self):
os.mkdir(self.__directory)
directory = StringRef("/tmp/dir1")
obj = SomeClass(directory)
obj.use_directory()
directory.set_value("/tmp/dir2")
obj.use_directory()
Output:
Traceback (most recent call last):
File "main.py", line 29, in <module>
obj.use_directory()
File "main.py", line 23, in use_directory
os.mkdir(self.__directory)
OSError: [Errno 17] File exists: '/tmp/dir1'