【问题标题】:Cannot access property from a method added to a python class无法从添加到 python 类的方法访问属性
【发布时间】:2019-09-18 03:34:41
【问题描述】:

我的程序使用MethodType 向类添加方法。问题是当代码试图访问一个属性时,它获取的是一个属性对象而不是获取属性值。代码如下:

#!/usr/bin/env python3

from types import MethodType

from ev3dev2.sensor import *
from ev3dev2.sensor.lego import LightSensor

# methods that extend the class
def set_calibration(self,min_value,max_value):
    self.min_value = min_value
    self.max_value = max_value
    self.value_range = max_value - min_value

def read_calibrated(self):
    value = self.reflected_light_intensity
    print(value)
    return 100 * ( value - self.min_value ) / self.value_range

LightSensor.set_calibration = MethodType( set_calibration, LightSensor )
LightSensor.read_calibrated = MethodType( read_calibrated, LightSensor )

# create class instance
light_left  = LightSensor(INPUT_2)
light_left.set_calibration( 20, 60 )

print(light_left.reflected_light_intensity)
print(light_left.read_calibrated())

当我运行程序时,它会产生以下输出和错误:

59.1
<property object at 0xb69f3fc0>
Traceback (most recent call last):
  File "./property_test.py", line 27, in <module>
    print(light_left.read_calibrated())
  File "./property_test.py", line 17, in read_calibrated
    return 100 * ( value - self.min_value ) / self.value_range
TypeError: unsupported operand type(s) for -: 'property' and 'int'

我也试过用这个:

def read_calibrated(self):
    # use underscore to get property value
    value = self._reflected_light_intensity
    print(value)
    return 100 * ( value - self.min_value ) / self.value_range

但这产生了一个错误:AttributeError: type object 'LightSensor' has no attribute '_reflected_light_intensity'

那么,回到原来的代码,为什么light_left.reflected_light_intensity返回一个数字,而self.reflected_light_intensity返回一个属性对象呢?

更重要的是,我如何从read_calibrated() 访问属性值?

Python 版本是 3.5.3。

【问题讨论】:

    标签: python python-3.x class properties


    【解决方案1】:

    如果您向类而不是实例对象添加方法,您可以简单地通过LightSensor.set_calibration=set_calibration 挂钩它。 MethodType 用于为类实例添加绑定方法。

    class LightSensor:
        def __init__(self):
            self.min_value = 1
            self.max_value = 2
            self.value_range = None
            self._reflected_light_intensity = 3
    
        def __repr__(self):
            return f"min: {self.min_value}, " \
                   f"max: {self.max_value}, " \
                   f"value_range: {self.value_range}, " \
                   f"reflected_intensity: {self._reflected_light_intensity}"
    
    def set_calibration(self,min_value,max_value):
        self.min_value = min_value
        self.max_value = max_value
        self.value_range = max_value - min_value
    
    def read_calibrated(self):
        value = self._reflected_light_intensity
        print(value)
        return 100 * ( value - self.min_value ) / self.value_range
    
    LightSensor.set_calibration = set_calibration
    LightSensor.read_calibrated = read_calibrated
    
    a = LightSensor()
    a.set_calibration(20,60)
    print (a)
    print (a.read_calibrated())
    
    b = LightSensor()
    
    print (b)
    

    结果:

    min: 20, max: 60, value_range: 40, reflected_intensity: 3
    3
    -42.5
    min: 1, max: 2, value_range: None, reflected_intensity: 3
    

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      相关资源
      最近更新 更多