我想编写一个类,其实例应该可以用作os.mkdir()的参数。有没有一个神奇的方法,我可以添加到我的班级,以便这可以工作?使用__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)
导致以下错误:
/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
我想在上下文中使用MyClass的实例,否则需要str或unicode。 E. g。为了制作&#34; abc&#34; + MyClass(&#34; def&#34;)工作,我可以在MyClass中实现__radd __()魔术方法。
编辑:解释我的意图的新代码示例(上面的MyClass对应于下面的StringRef):
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()
输出:
* 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)避免TypeError但不创建/ 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()
输出:
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'
答案 0 :(得分:1)
因为你希望这只小狗表现得像一个字符串,抱歉unicode,只是从unicode(内置的unicode类)而不是object中继承它。
#as per Padraic's remark that string <> unicode
#class MyClass(str):
class MyClass(unicode):
pass
obj = MyClass("/tmp/dir")
print unicode(obj)
os.mkdir(obj)
#surprised that assigning a new attribute here works
#I woulda thought MyClass
#would be using __slots__. oh well, better for you.
obj.foo = 1
print "obj.foo:%s" % (obj.foo)
答案 1 :(得分:0)
这是怎么回事?
(文件是testmkdir2.py) import os
class MonkeyPatch(object):
def __init__(self):
self.func = os.mkdir
def __call__(self, sortastring):
if hasattr(sortastring,"value"):
self.func(sortastring.value)
else:
self.func(sortastring)
mk = MonkeyPatch()
os.mkdir = mk
os.mkdir("/tmp/foo")
class Dummy(object):
pass
sneakystring = Dummy()
sneakystring.value = "/tmp/foo2"
os.mkdir(sneakystring)
sneakystring.value = "/tmp/foo3"
os.mkdir(sneakystring)
$ ls -l / tmp / | grep foo $
$ python testmkdir2.py
$ ls / tmp / | grep foo
drwxr-xr-x 2 jluc wheel 68 26 Feb 20:19 foo
drwxr-xr-x 2 jluc wheel 68 26 Feb 20:19 foo2
drwxr-xr-x 2 jluc wheel 68 26 Feb 20:19 foo3
答案 2 :(得分:0)
我认为在传递给各种对象后,有一个字符串引用可以更改其值的最简洁方法是使用包含字符串值的对象并更改字符串引用的执行上下文与它的方式不同看起来如果使用字符串而不是字符串引用:新的执行上下文将是os.mkdir(s.value),&#34; string&#34; + s.value,s.value +&#34; string&#34;而不是os.mkdir(s),&#34; string&#34; + s,s +&#34; string&#34;):
class StringRef(object):
def __init__(self, value):
self.__value = value
@property
def value(self):
return self.__value
@value.setter
def value(self, val):
self.__value = val
class SomeClass(object):
def __init__(self, s):
self.__s = s
def meth(self):
print self.__s.value # new execution context here
directory = StringRef("/tmp")
obj = SomeClass(directory)
obj.meth()
directory.value = "/var"
obj.meth()