Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 构造一个对象,该对象在每次被访问时都会更改其状态,其行为类似于变量_Python_Properties - Fatal编程技术网

Python 构造一个对象,该对象在每次被访问时都会更改其状态,其行为类似于变量

Python 构造一个对象,该对象在每次被访问时都会更改其状态,其行为类似于变量,python,properties,Python,Properties,我想用一种特殊的行为构造一个对象,我很确定它可以用python(用生成器或某种复杂的类定义)来完成 我基本上想要一个对象——我们称之为——colorgun,每次访问它时,它都会从预定义的颜色列表中返回一种颜色。所以它的行为应该像一个简单的变量,但每次访问它时都会改变它的行为 您可以在以下示例中看到一个类似的概念: class CounterList(list): def __init__(self, *args): super(CounterList, self).__i

我想用一种特殊的行为构造一个对象,我很确定它可以用python(用生成器或某种复杂的类定义)来完成

我基本上想要一个对象——我们称之为——
colorgun
,每次访问它时,它都会从预定义的颜色列表中返回一种颜色。所以它的行为应该像一个简单的变量,但每次访问它时都会改变它的行为

您可以在以下示例中看到一个类似的概念:

class CounterList(list):
    def __init__(self, *args):
        super(CounterList, self).__init__(*args)
        self.counter = 0
    def __getitem__(self, index):
        self.counter += 1
        return super(CounterList, self).__getitem__(index)
计数器列表
的实例在每次访问该列表时都会增加
计数器
,因为调用了
\uuuu getitem\uuuu

我的
colorgun
应该能够在“使用”时检测到,并表现出如下行为:

>>> gun = Colourgun() # or a function, a generator, whatever...
>>> print gun
'predefined_colour1'
>>> print gun
'predefined_colour2'
>>> print gun
'predefined_colour3'
>>> print gun # no more colours left: reloading and maybe warn the user
[WARNING] automatically reloading the gun
'predefined_colour1'
>>> gun.load(['colour1', 'colour2', 'colour3']) # some way to load it with colours
>>> print gun
'colour1'
>>> print gun
'colour2'
>>> gun.reload() # manually reloading
>>> print gun
'colour1'
关键是,我不想每次访问变量时都显式调用“拍摄颜色”的方法。我想这是一个迹象,表明变量确实应该是一个函数或生成器(至少可以冻结其状态)

我做了一点实验,这是一次尝试,试图更接近这个想法,但它不起作用,因为我将Shoot()的返回值绑定到变量
gun

class ColourGun(object) :
    def __init__(self) :
        self.colours = ['predefined_colour1', 'predefined_colour2', 'predefined_colour3']
        self.counter = 0
    def Shoot(self) :
        c = self.colours[self.counter]
        self.counter += 1
        return c

gun = ColorGun().Shoot()

print gun
print gun
print gun
当然,它会打印出
预定义的\u color1
三次

因此,肯定有一个基于生成器的概念,或者类和生成器的组合,或者其他一些概念,可以用python的方式来实现。(或者可能是设计模式?)

附言:如果你有更好的标题的想法,请告诉我,并随时添加更多标签

更新

因此,使用属性执行此操作(如wim建议的):

它给出了输出:

predefined_colour1
predefined_colour2
predefined_colour3
automatically reloading
predefined_colour1

实现一个
重新加载
方法没有问题,但是我能以某种方式摆脱这个
,这样我就可以像
一样调用它,而不是
枪。射击
?;-)

像这样的东西

import itertools as it

class ColourGun(object):

    def __init__(self):
        self._colourgen = it.cycle(['predefined_colour1', 'predefined_colour2', 'predefined_colour3'])

    def load(self, colours):
        self._colourgen = it.cycle(colours)

    @property
    def colour(self):
        return next(self._colourgen)

    def __str__(self):
      return self.colour

gun = ColourGun()
print gun
print gun
print gun
gun.load(['potato', 'spam', 'eggs'])
print gun
print gun

因为您的
正在使用
意味着
打印枪
,所以让我们定制
\uuuu str\uuu
方法

class ColorGun:

    def __init__(self):
        self.colors = ['red', 'pink']
        self.i = 0

    def __str__(self):
        if not self.colors:
            return

        if self.i >= len(self.colors):
            print '[WARNING] automatically reloading the gun.'
            self.reload()

        c = self.colors[self.i]
        self.i += 1

        return c

    def reload(self, colors=None):
        if colors:
            self.colors = colors
        self.i = 0

gun = ColorGun()
print gun
print gun
print gun

您可能需要自定义
\uuuu str\uuuu
函数以实现此目的。这里有一个简单的例子

此示例显示了
mylist
(您可以使用生成器)中的项,当生成器用尽时,它会打印一个默认值

class Gun():
    mylist=[1,2,3]
    index=-1
    default='Default'
    def __str__(self):
        try:
            self.index+=1
            return str(self.mylist[self.index])
        except IndexError:
            return self.default


>>> gun=Gun()
>>> print gun
1
>>> print gun
2
>>> print gun
3
>>> print gun
Default
>>> 

你想看看房产。啊,好的,谢谢,我想我知道了…你怎么摆脱这个
gun=ColorGun()。Shoot
。请参阅公认的答案:您使用这样一个事实,即只要变量作为字符串请求,就会调用
\uuuuu str\uuuu
。因此,您可以修改
\uuuu str\uuuu
以返回其属性
color
等。我不是想劫持线程,但是你能举例说明这种技术何时有用吗?我理解财产和``````````````````````````````````````````````````````` str``````。我不确定这是否有责任。谢谢,看起来不错:)@CppLearner当我生成一组图并想要使用自己的颜色光谱时,我正在使用这个。现在,我可以使用
gun
或它的任何名称作为变量,每次都会改变颜色,因此单个绘图中的多行打印有不同的颜色。属性在属性获取、设置或删除时非常有用。一个常见的用法示例是限制一个属性,使其只能设置为一组受控的输入。这仅在您调用对象上的
str
时有效。。。例如打印时。不适用于访问的一般情况。
class Gun():
    mylist=[1,2,3]
    index=-1
    default='Default'
    def __str__(self):
        try:
            self.index+=1
            return str(self.mylist[self.index])
        except IndexError:
            return self.default


>>> gun=Gun()
>>> print gun
1
>>> print gun
2
>>> print gun
3
>>> print gun
Default
>>>