Python 类的 getter 和 setter 静态方法及类方法
class Spam(object):
#a_string = 'candy'
def __init__(self, sold=0, cost=0):
self.sold = sold
self.cost = cost
@staticmethod
def total_cost():
return True
@classmethod
def items_sold(cls, how_many):
@property
def silly_walk(self):
return print (self.a_string)
@silly_walk.setter
def silly_walk(self, new_string):
self.a_string = new_string.upper()
def do_cost(self):
if self.total_cost():
print('Total cost is:', self.cost)
.
from spam import Spam
def main ():
cost = 25
sold = 100
a_string = 'sweets'
sp = Spam(100, 25)
sp.do_cost()
sw = Spam.silly_walk(a_string)
sw.silly_walk()
if __name__ == '__main__':
main()
我刚开始学Python,不太明白怎么用设置器和获取器。我的目标是:
用@property来为一个叫silly_walk的属性创建设置器和获取器。设置器要把silly_walk字符串变成大写。
展示一些示例代码,说明如何访问这个静态方法。
展示一些示例代码,说明如何使用silly_walk的设置器和获取器。
我对类里面的“self”有点困惑,不太确定我做的是否正确。
更新:问题出在@classmethod没有返回值和缩进错误,现在一切都解决了,谢谢大家。
1 个回答
0
self
是一种约定。在类里面,你不是在写函数,而是在写方法。方法需要一个指向调用它的对象的引用作为第一个参数,按照约定,这个参数叫做 self
。其实你可以把它叫成任何名字。
class Foo(object):
def __init__(itsa_me_maaaario, name):
itsa_me_maaario.name = "Mario"
这样也完全可以。
至于你代码的其他部分——你想问什么呢?看起来你的设置方法有点奇怪,不过除此之外,其他部分应该大致没问题。这样写会更好:
class Spam(object): # inherit from object in py2 for new-style classes
def __init__(self, a_string, sold=0, cost=0) # put the positional arg first
...
@staticmethod
def total_cost():
# you have to do something meaningful here. A static method can't access
# any of the objects attributes, it's really only included for grouping
# related functions to their classes.
@classmethod
def items_sold(cls, how_many):
# the first argument to a classmethod is the class, not the object, so
# by convention name it cls. Again this should be something relevant to
# the class not to the object.
@property
def silly_walk(self):
return self.a_string
# don't call itself.
@silly_walk.setter
def silly_walk(self, new_string):
self.a_string = new_string
# it really just hides the attribute.
举个例子,我有一个类是用来抽象我负责的计算机系统的。可能是这样的:
class System(object):
type_ = "Base system"
def __init__(self, sitenum, devicenum, IP):
self._sitenum = sitenum
self._devicenum = devicenum
self._IP = IP
# the leading underscores are a flag to future coders that these are
# "private" variables. Nothing stopping someone from using it anyway,
# because System()._IP is still that attribute, but it makes it clear
# that they're not supposed to be used that way.
@staticmethod
def ping_system(IP):
subprocess.call(["ping",IP], shell=True) # OH GOD SECURITY FLAW HERE
# group this with Systems because maybe that's how I want it? It's an
# aesthetic choice. Note that this pings ANY system and requires an
# argument of an IP address!
@classmethod
def type_of_system(cls):
return cls.type_
# imagine I had a bunch of objects that inherited from System, each w/
# a different type_, but they all inherit this....
@property
def description(self):
return "Site {}, Device {} @ {}".format(self._sitenum,
self._devicenum,
self._IP)
@description.setter
def description(self, *args):
if len(args) == 3:
self._sitenum, self._devicenum, self._IP = args
elif len(args) == 1 and len(args[0]) == 3:
self._sitenum, self._devicenum, self._IP = args[0]
else:
raise ValueError("Redefine description as Sitenum, Devicenum, IP")
示例:
computer = System(1, 1, '192.168.100.101')
System.ping_system('192.160.100.101') # works
computer.type_of_system # "Base system"
computer.description # "Site 1, Device 1 @ 192.168.100.101"
new_description = [1, 2, '192.168.100.102']
computer.description = new_description
# invokes description.setter
computer._devicenum # is 2 after the setter does its magic.