注意:我看到我需要更清楚地弄清楚我要每个属性/描述符/类/方法要做什么,然后再问如何做!我认为目前无法回答我的问题。谢谢大家的帮助。
多亏了icktoofay和BrenBarn,我才开始了解描述符和属性,但是现在我有一个稍微困难的问题要问:
我现在看到这些是如何工作的:
class Blub(object):
def __get__(self, instance, owner):
print('Blub gets ' + instance._blub)
return instance._blub
def __set__(self, instance, value):
print('Blub becomes ' + value)
instance._blub = value
class Quish(object):
blub = Blub()
def __init__(self, value):
self.blub = value
以及a = Quish('one')的工作原理(产生“ Blub变成一个”),但是在下面的代码中有个缺点:
import os
import glob
class Index(object):
def __init__(self, dir=os.getcwd()):
self.name = dir #index name is directory of indexes
# index is the list of indexes
self.index = glob.glob(os.path.join(self.name, 'BatchStarted*'))
# which is the pointer to the index (index[which] == BatchStarted_12312013_115959.txt)
self.which = 0
# self.file = self.File(self.index[self.which])
def get(self):
return self.index[self.which]
def next(self):
self.which += 1
if self.which < len(self.index):
return self.get()
else:
# loop back to the first
self.which = 0
return None
def back(self):
if self.which > 0:
self.which -= 1
return self.get()
class File(object):
def __init__(self, file):
# if the file exists, we'll use it.
if os.path.isfile(file):
self.name = file
# otherwise, our name is none and we return.
else:
self.name = None
return None
# 'file' attribute is the actual file object
self.file = open(self.name, 'r')
self.line = Lines(self.file)
class Lines(object):
# pass through the actual file object (not filename)
def __init__(self, file):
self.file = file
# line is the list if this file's lines
self.line = self.file.readlines()
self.which = 0
self.extension = Extension(self.line[self.which])
def __get__(self):
return self.line[self.which]
def __set__(self, value):
self.which = value
def next(self):
self.which += 1
return self.__get__()
def back(self):
self.which -= 1
return self.__get__()
class Extension(object):
def __init__(self, lineStr):
# check to make sure a string is passed
if lineStr:
self.lineStr = lineStr
self.line = self.lineStr.split('|')
self.pathStr = self.line[0]
self.path = self.pathStr.split('\\')
self.fileStr = self.path[-1]
self.file = self.fileStr.split('.')
else:
self.lineStr = None
def __get__(self):
self.line = self.lineStr.split('|')
self.pathStr = self.line[0]
self.path = self.pathStr.split('\\')
self.fileStr = self.path[-1]
self.file = self.fileStr.split('.')
return self.file[-1]
def __set__(self, ext):
self.file[-1] = ext
self.fileStr = '.'.join(self.file)
self.path[-1] = fileStr
self.pathStr = '\\'.join(self.path)
self.line[0] = self.pathStr
self.lineStr = '|'.join(self.line)
首先,这里可能会有一些错别字,因为我一直在努力处理,半途而废。那不是我的意思。我的观点是,在icktoofay的示例中,没有任何东西传递给Blub()。有什么办法可以做我在这里做的事情,那就是设置一些“自我”属性,并在进行一些处理之后,将其传递给下一个类?这会更适合物业吗?
我想要这样:
>>> i = Index() # i contains list of index files
>>> f = File(i.get()) # f is now one of those files
>>> f.line
'\\\\server\\share\\folder\\file0.txt|Name|Sean|Date|10-20-2000|Type|1'
>>> f.line.extension
'txt'
>>> f.line.extension = 'rtf'
>>> f.line
'\\\\server\\share\\folder\\file0.rtf|Name|Sean|Date|10-20-2000|Type|1'
最佳答案
您可以执行此操作,但是问题很少涉及属性/描述符,而更多地涉及创建提供所需行为的类。
因此,当您执行f.line
时,这就是一些对象。当您执行f.line.extension
时,即正在执行(f.line).extension
---即,它首先评估f.line
,然后获取任何extension
的f.line
属性。
这里重要的是f.line
无法知道您以后是否要尝试访问其extension
。因此,您不能让f.line
为“普通” f.line
做一件事,而为f.line.extension
做另一件事。两者之间的f.line
部分必须相同,并且extension
部分不能更改。
解决方案似乎是使f.line
返回某种对象,该对象以某种方式看起来或类似于字符串,但还允许设置属性并相应地更新自身。确切的操作方式取决于f.lines
需要多少才能像字符串一样工作以及执行其他工作需要多少。基本上,您需要f.line
作为“网关守卫”对象,该对象通过像字符串一样处理某些操作(例如,您显然希望它显示为字符串),并以自定义方式处理其他对象(例如,您显然希望能够在其上设置extension
属性并对其内容进行更新)。
这是一个简单的例子:
class Line(object):
def __init__(self, txt):
self.base, self.extension = txt.split('.')
def __str__(self):
return self.base + "." + self.extension
现在您可以执行以下操作:
>>> line = Line('file.txt')
>>> print line
file.txt
>>> line.extension
'txt'
>>> line.extension = 'foo'
>>> print line
file.foo
但是,请注意,我做了
print line
,而不仅仅是line
。通过编写__str__
方法,我定义了执行print line
时发生的行为。但是,如果您不打印而将其评估为“原始”,就会发现它并不是真正的字符串:>>> line
<__main__.Line object at 0x000000000233D278>
您也可以覆盖此行为(通过定义
__repr__
),但是您想这么做吗?这取决于您要如何使用line
。关键是您需要确定line
在什么情况下要做什么,然后设计一个可以做到这一点的类。关于python - Python中的“子类”和self,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19851426/