我这样做:
def set_property(property,value):
def get_property(property):
or
object.property = value
value = object.property
python使用getter和setter的方法是什么?
我这样做:
def set_property(property,value):
def get_property(property):
or
object.property = value
value = object.property
python使用getter和setter的方法是什么?
当前回答
试试这个:Python属性
示例代码如下:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
@x.setter
def x(self, value):
print("setter of x called")
self._x = value
@x.deleter
def x(self):
print("deleter of x called")
del self._x
c = C()
c.x = 'foo' # setter called
foo = c.x # getter called
del c.x # deleter called
其他回答
你可以使用神奇的方法__getattribute__和__setattr__。
class MyClass:
def __init__(self, attrvalue):
self.myattr = attrvalue
def __getattribute__(self, attr):
if attr == "myattr":
#Getter for myattr
def __setattr__(self, attr):
if attr == "myattr":
#Setter for myattr
注意__getattr__和__getattribute__是不同的。__getattr__只在未找到属性时调用。
使用@property和@attribute。Setter不仅可以帮助您使用“pythonic”方式,还可以在创建对象和更改对象时检查属性的有效性。
class Person(object):
def __init__(self, p_name=None):
self.name = p_name
@property
def name(self):
return self._name
@name.setter
def name(self, new_name):
if type(new_name) == str: #type checking for name property
self._name = new_name
else:
raise Exception("Invalid value for name")
通过这种方式,您实际上可以向客户端开发人员“隐藏”_name属性,并对name属性类型进行检查。请注意,即使在初始化过程中也会调用setter。所以:
p = Person(12)
会导致:
Exception: Invalid value for name
But:
>>>p = person('Mike')
>>>print(p.name)
Mike
>>>p.name = 'George'
>>>print(p.name)
George
>>>p.name = 2.3 # Causes an exception
python使用getter和setter的方法是什么?
“Pythonic”的方法不是使用“getter”和“setter”,而是使用简单的属性,就像问题所演示的那样,以及del用于删除(但是为了保护无辜的人,更改了名称……内置命令):
value = 'something'
obj.attribute = value
value = obj.attribute
del obj.attribute
如果稍后,你想修改设置和获取,你可以这样做,而不必修改用户代码,通过使用属性装饰器:
class Obj:
"""property demo"""
#
@property # first decorate the getter method
def attribute(self): # This getter method name is *the* name
return self._attribute
#
@attribute.setter # the property decorates with `.setter` now
def attribute(self, value): # name, e.g. "attribute", is the same
self._attribute = value # the "value" name isn't special
#
@attribute.deleter # decorate with `.deleter`
def attribute(self): # again, the method name is the same
del self._attribute
(每次使用装饰器都会复制并更新前面的属性对象,因此请注意,您应该为每个set、get和delete函数/方法使用相同的名称。)
在定义了上面的代码之后,原来的设置、获取和删除代码是一样的:
obj = Obj()
obj.attribute = value
the_value = obj.attribute
del obj.attribute
你应该避免这样做:
def set_property(属性,值): def get_property(财产):
首先,上面的方法不起作用,因为你没有为属性将要设置为的实例提供参数(通常是self),即:
class Obj:
def set_property(self, property, value): # don't do this
...
def get_property(self, property): # don't do this either
...
其次,这重复了两个特殊方法__setattr__和__getattr__的目的。
第三,我们还有setattr和getattr内置函数。
setattr(object, 'property_name', value)
getattr(object, 'property_name', default_value) # default is optional
@property装饰器用于创建getter和setter。
例如,我们可以修改设置行为来限制正在设置的值:
class Protective(object):
@property
def protected_value(self):
return self._protected_value
@protected_value.setter
def protected_value(self, value):
if acceptable(value): # e.g. type or range check
self._protected_value = value
一般来说,我们希望避免使用属性,而只是使用直接属性。
这是Python用户所期望的。遵循最小惊喜原则,你应该尽量满足用户的期望,除非你有非常令人信服的相反理由。
示范
例如,我们需要我们的对象的protected属性是一个0到100之间的整数,并防止它的删除,用适当的消息告知用户它的正确用法:
class Protective(object):
"""protected property demo"""
#
def __init__(self, start_protected_value=0):
self.protected_value = start_protected_value
#
@property
def protected_value(self):
return self._protected_value
#
@protected_value.setter
def protected_value(self, value):
if value != int(value):
raise TypeError("protected_value must be an integer")
if 0 <= value <= 100:
self._protected_value = int(value)
else:
raise ValueError("protected_value must be " +
"between 0 and 100 inclusive")
#
@protected_value.deleter
def protected_value(self):
raise AttributeError("do not delete, protected_value can be set to 0")
(注意,__init__指的是self。但属性方法引用self._protected_value。这样,__init__就可以通过公共API使用该属性,确保它是“受保护的”。)
和用法:
>>> p1 = Protective(3)
>>> p1.protected_value
3
>>> p1 = Protective(5.0)
>>> p1.protected_value
5
>>> p2 = Protective(-5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> p1.protected_value = 7.3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 17, in protected_value
TypeError: protected_value must be an integer
>>> p1.protected_value = 101
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> del p1.protected_value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 18, in protected_value
AttributeError: do not delete, protected_value can be set to 0
名字重要吗?
是的。setter和。deleter会复制原始属性。这允许子类在不改变父类中的行为的情况下正确地修改行为。
class Obj:
"""property demo"""
#
@property
def get_only(self):
return self._attribute
#
@get_only.setter
def get_or_set(self, value):
self._attribute = value
#
@get_or_set.deleter
def get_set_or_delete(self):
del self._attribute
现在为了让它工作,你必须使用各自的名称:
obj = Obj()
# obj.get_only = 'value' # would error
obj.get_or_set = 'value'
obj.get_set_or_delete = 'new value'
the_value = obj.get_only
del obj.get_set_or_delete
# del obj.get_or_set # would error
我不确定这在什么情况下有用,但用例是如果您想要一个get、set和/或delete-only属性。可能最好是使用语义上相同的属性和相同的名称。
结论
从简单的属性开始。
如果以后需要设置、获取和删除相关的功能,可以使用属性装饰器添加它。
避免使用名为set_…和get_……-这就是属性的作用。
试试这个:Python属性
示例代码如下:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
@x.setter
def x(self, value):
print("setter of x called")
self._x = value
@x.deleter
def x(self):
print("deleter of x called")
del self._x
c = C()
c.x = 'foo' # setter called
foo = c.x # getter called
del c.x # deleter called
In [1]: class test(object):
def __init__(self):
self.pants = 'pants'
@property
def p(self):
return self.pants
@p.setter
def p(self, value):
self.pants = value * 2
....:
In [2]: t = test()
In [3]: t.p
Out[3]: 'pants'
In [4]: t.p = 10
In [5]: t.p
Out[5]: 20