Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;“子类”;Python中的self和self_Python_Descriptor - Fatal编程技术网

&引用;“子类”;Python中的self和self

&引用;“子类”;Python中的self和self,python,descriptor,Python,Descriptor,注意:我发现我需要更清楚地了解我希望每个属性/描述符/类/方法做什么,然后再询问如何做!我认为我的问题目前无法回答。谢谢大家帮助我 多亏了icktoofay和BrenBarn,我开始理解描述者和属性,但现在我有一个稍微难一点的问题要问: 我现在明白了这些是如何工作的: class Blub(object): def __get__(self, instance, owner): print('Blub gets ' + instance._blub) re

注意:我发现我需要更清楚地了解我希望每个属性/描述符/类/方法做什么,然后再询问如何做!我认为我的问题目前无法回答。谢谢大家帮助我

多亏了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(‘一’)是如何工作的(产生“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
a
str
还是
line
?如果您在
中添加(比如)一个
find
方法,您希望
f.line.find()
调用
str
find
实现还是
实现?为什么?我更新了我的问题,以反映我意识到在我试图做的事情中的模糊性。在我开始询问如何使用程序之前,我需要确定我希望程序如何工作。你的思维实验可能是:
f.line
a
str
或a
line
?如果您在
中添加(比如)一个
find
方法,您希望
f.line.find()
调用
str
find
实现还是
实现?为什么?我更新了我的问题,以反映我在尝试中意识到的模糊性