Python:使用@property装饰器时直接访问setter的属性方法

时间:2018-03-28 10:01:44

标签: python properties pyqt pyside getter-setter

我想在python中使用属性,同时仍然能够在某些情况下直接调用属性的setter方法。原因是,我需要在使用PySide / PyQt时在lambda语句中分配变量。

以下示例包含两个应该表现几乎完全相同的类。一个使用property()和一个@property

class Test1:
    def __init__(self):
        self._x = 0

    def setx(self, value):
        print(f'x set to {value}')
        self._x = value

    x = property(fset=setx)


class Test2:
    def __init__(self):
        self._x = False

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        print(f'x set to {value}')
        self._x = value


t1 = Test1()
print('Test1:')
t1.x = 1
setattr(t1, 'x', 2)
t1.setx(3)


t2 = Test2()
print('Test2:')
t2.x = 1
setattr(t2, 'x', 2)

这非常有效。对于类Test1,我可以使用3种不同的方式为变量赋值。其中2个可以在lambda语句中使用。

但是,如果我使用@property装饰器,我只剩下两种方式(据我所知至少!)。并且在lambda语句中分配的唯一可能方法是使用setattr,我宁愿避免,因为在我看来它会损害可读性:(

问题

有没有办法使用@property装饰器的句法糖,同时仍能直接使用setter?

1 个答案:

答案 0 :(得分:1)

编辑:实际上,有一种方法可以做到这一点

<script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js" integrity="sha384-8iPTk2s/jMVj81dnzb/iFR2sdA7u06vHJyyLlAd4snFpCl/SnyUjRrbdJsw1pGIl" crossorigin="anonymous"></script>
   <?php

      $onderrwerp = $app->get_onderwerpen();
      foreach($onderrwerp as $onderwerp){
        echo '<div class="well well-sm">';
            if(file_exists('assets/images/profielfotos/'.$onderwerp['klant_id'])) { 
                echo '<img class="img-circle" src="/assets/images/profielfotos/'.$onderwerp['klant_id'].'/'.$onderwerp['foto'].'" />';
            } else {
                echo '<i style="font-size: 6em;" class="fas fa-user-circle"></i>';
            }
            echo '<b><a href="https://tom.lbmedia.nl/reactie"> '.$onderwerp['onderwerpnaam'].'</b></a>'; 
            echo ' - ' . $onderwerp['voornaam'] . ' ' . $onderwerp['achternaam'];
            echo '</div>';
        }
    ?>

但这比class C: def __init__(self): self._x = 4 @property def x(self): return self._x @x.setter def x(self, x): self._x = x c = C() c.x == 4 C.x.fset(c, 3) c.x == 3 的可读性低得多,所以我不会使用它。

不,没有。但是你不应该指望那样。

现在抱怨你只有两种不同的方法来做某事不是一个好的论据。

就像@ Aran-Fey所说,你可以在你的例子中使用真实的setattr函数或def。使用这些并没有错,任何在python中值得盐的人都会明白发生了什么。