- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Python 3.x 中,是否可以创建一个可以被许多类重用的"template"属性?
我有大约 200 个类与商店中销售的产品相对应。每个类都使用特定于产品的属性。每个属性的“get”和“let”函数有时会在设置属性值时对数据执行详细的健全性检查。
有时对许多不同类的许多不同属性执行相同的检查。唯一改变的是属性名称。下面为“Robot”和“Box”类提供了一个简化示例。在这些类中,属性会检查是否将其设置为小于 1 的值并进行更正。
class Robot():
def setPrice(self,Price): # <--
# <--
if (Price < 1): Price = 1 # <--
# <-- Common check
self.__Price = Price # <-- to many
# <-- classes
def getPrice(self): # <--
# <--
return self.__Price # <--
# <--
Price = property(getPrice, setPrice) # <--
class Box():
def setWeight(self,Weight): # <--
# <--
if (Weight < 1): Weight = 1 # <--
# <-- Common check
self.__Weight = Weight # <-- to many
# <-- classes
def getWeight(self): # <--
# <--
return self.__Weight # <--
# <--
Weight = property(getWeight, setWeight) # <--
是否可以将此属性隔离到类的某种外部函数中,然后我的许多类都可以调用它?换句话说,这样的东西能实现吗?
class_or_function TemplateProperty():
... some code ...
class Robot():
Price = TemplateProperty()
NumberOfLegs = TemplateProperty()
class Box():
Price = TemplateProperty()
Weight = TemplateProperty()
Height = TemplateProperty()
Length = TemplateProperty()
最佳答案
如果您的对象永远不会有多个模板属性,那么您可以编写一个简单的函数来构建一个适当的属性对象并返回它:
def PositiveValuedProperty():
def getter(obj):
return obj.__value
def setter(obj, new_value):
if new_value < 1:
new_value = 1
obj.__value = new_value
return property(getter, setter)
那么你的类(class)将是:
class Robot:
Price = PositiveValuedProperty()
class Box:
Weight = PositiveValuedProperty()
但是,如果任何类使用这些属性的倍数,这将不起作用,因为它们都写入相同的属性名称。如果你想在一个类中允许多个,你可能需要为工厂函数指定一个属性名称:
def PositiveValuedProperty(name):
name = "_" + name
def getter(obj):
return getattr(obj, name)
def setter(obj, new_value):
if new_value < 1:
new_value = 1
setattr(obj, name, new_value)
return property(getter, setter)
现在你可以设置一个 RobotBox
与 Price
和一个 Weight
:
def RobotBox():
Price = PositiveValuedProperty("Price")
Weight = PositiveValuedProperty("Weight")
实际值将存储在属性 _Price
中和 _Weight
如果您希望内部代码无需通过 property
即可访问它们的支票。
请注意,如果您的逻辑比上面的复杂得多,您最好构建自己的描述符类型,而不是创建闭包并将它们传递给 property
构造函数,就像我上面所做的那样。一个描述符只是一个带有一些 __get__
的类, __set__
和/或 __delete__
根据 descriptor protocol 定义的方法.以下是如何实现 PositiveValuedProperty
的最新版本作为描述符类而不是工厂函数:
class PositiveValuedProperty():
def __init__(self, name):
self.name = "_" + name
def __get__(self, obj, cls=None):
return getattr(obj, self.name)
def __set__(self, obj, new_value):
if new_value < 1:
new_value = 1
setattr(obj, self.name, new_value)
如您所见,它几乎与 property
相同代码,因为property
是一个描述符,它使用您传递给它的函数来实现其 __get__
和 __set__
方法。但是,您可以编写更复杂的描述符。例如,如果你愿意,你可以通过检查 type(obj)
的属性来让你的描述符推断出它自己的名字。 (或 cls
参数到 __get__
)并寻找一个等于 self
的参数.不过这有点脆弱,因为描述符实际上可能有多个名称(例如 class Foo: x=MyDescritptor(); y=x
)并且搜索类的变量可能很慢。
关于class - Python 3.4 - 如何为多个类创建模板属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35108495/
我是一名优秀的程序员,十分优秀!