&引用;“子类”;Python中的self和self
注意:我发现我需要更清楚地了解我希望每个属性/描述符/类/方法做什么,然后再询问如何做!我认为我的问题目前无法回答。谢谢大家帮助我 多亏了icktoofay和BrenBarn,我开始理解描述者和属性,但现在我有一个稍微难一点的问题要问: 我现在明白了这些是如何工作的:&引用;“子类”;Python中的self和self,python,descriptor,Python,Descriptor,注意:我发现我需要更清楚地了解我希望每个属性/描述符/类/方法做什么,然后再询问如何做!我认为我的问题目前无法回答。谢谢大家帮助我 多亏了icktoofay和BrenBarn,我开始理解描述者和属性,但现在我有一个稍微难一点的问题要问: 我现在明白了这些是如何工作的: class Blub(object): def __get__(self, instance, owner): print('Blub gets ' + instance._blub) re
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(‘一’)是如何工作的(产生“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)
可以这样做,但问题不在于属性/描述符,而在于创建提供所需行为的类 所以,当你做
f.line
时,这是一个对象。当您执行f.line.extension
时,即执行(f.line.extension
——也就是说,它首先计算f.line
,然后获取f.line
的extension
属性
这里重要的是,f.line
无法知道您以后是否要尝试访问其扩展名。所以你不能让f.line
为“普通”f.line
做一件事,为f.line.extension
做另一件事。f.line
部分必须在两者中相同,并且扩展部分不能改变这一点
您似乎想做的解决方案是让f.line
返回某种类型的对象,这些对象在某种程度上看起来或工作起来像字符串,但也允许设置属性并相应地更新自身。具体如何实现这一点取决于需要多少f.lines
才能像字符串一样工作,以及需要多少它来完成其他工作。基本上,您需要f.line
成为一个“看门人”对象,它通过像字符串一样处理某些操作(例如,您显然希望它显示为字符串),并以自定义方式处理其他对象(例如,您显然希望能够在其上设置扩展
属性并更新其内容)
这里有一个简单的例子:
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
但是,请注意,我确实打印了行
,而不仅仅是行
。通过编写\uuu str\uuu
方法,我定义了执行打印行时发生的行为。但如果您在未打印的情况下对其进行“原始”评估,您将看到它实际上不是一个字符串:
>>> line
<__main__.Line object at 0x000000000233D278>
>>行
您也可以覆盖此行为(通过定义\uuu repr\uuu
),但是否要?这取决于您想如何使用行
。关键是,您需要决定您的行在什么情况下要做什么,然后创建一个这样做的类。您可以这样做,但这里的问题不是关于属性/描述符,而是关于创建提供所需行为的类
所以,当你做f.line
时,这是一个对象。当您执行f.line.extension
时,即执行(f.line.extension
——也就是说,它首先计算f.line
,然后获取f.line
的extension
属性
这里重要的是,f.line
无法知道您以后是否要尝试访问其扩展名。所以你不能让f.line
为“普通”f.line
做一件事,为f.line.extension
做另一件事。f.line
部分必须在两者中相同,并且扩展部分不能改变这一点
您似乎想做的解决方案是让f.line
返回某种类型的对象,这些对象在某种程度上看起来或工作起来像字符串,但也允许设置属性并相应地更新自身。具体如何实现这一点取决于需要多少f.lines
才能像字符串一样工作,以及需要多少它来完成其他工作。基本上,您需要f.line
成为一个“看门人”对象,它通过像字符串一样处理某些操作(例如,您显然希望它显示为字符串),并以自定义方式处理其他对象(例如,您显然希望能够在其上设置扩展
属性并更新其内容)
这里有一个简单的例子:
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
但是,请注意,我确实打印了行
,而不仅仅是行
。通过编写\uuu str\uuu
方法,我定义了执行打印行时发生的行为。但如果您在未打印的情况下对其进行“原始”评估,您将看到它实际上不是一个字符串:
>>> line
<__main__.Line object at 0x000000000233D278>
>>行
您也可以覆盖此行为(通过定义\uuu repr\uuu
),但是否要?这取决于您想如何使用行
。关键是你需要决定你的行在什么情况下要做什么,然后设计一个这样做的类。思想实验,也许是:是f.line
astr
还是line
?如果您在行
中添加(比如)一个find
方法,您希望f.line.find()
调用str
的find
实现还是行
的实现?为什么?我更新了我的问题,以反映我意识到在我试图做的事情中的模糊性。在我开始询问如何使用程序之前,我需要确定我希望程序如何工作。你的思维实验可能是:f.line
astr
或aline
?如果您在行
中添加(比如)一个find
方法,您希望f.line.find()
调用str
的find
实现还是行
的实现?为什么?我更新了我的问题,以反映我在尝试中意识到的模糊性