假设我有一个文件“icon.ico”和一个网址“url.com”
在课堂上只使用一次 - “icon.ico”将设置为某个窗口,我们将在一个方法中执行url请求。
我有三种方法来定义这些变量。
第一种方式 - 定义为全局常量
#in the top of the file
ICON = "icon.ico"
URL = "http://url.com"
#and then
def setIcon(self):
self.setWindowIcon(QtGui.QIcon(ICON))
def getData(self):
content = requests.get(URL).content
第二种方式 - 定义为类的变量
def __init__(self):
self.url = "http://url.com"
self.icon = "icon.ico"
第三种方式 - 在方法中定义
def setIcon(self):
icon = "icon.ico"
def getData(self):
url = "http://url.com"
答案 0 :(得分:5)
而不是:
def __init__(self):
self.url = "http://url.com"
self.icon = "icon.ico"
或
def setIcon(self):
icon = "icon.ico"
是可取的:
def __init__(self, url, icon):
self.url = url
self.icon = icon
或者,如果您认为这些值将是90%相同:
def __init__(self, url="http://url.com", icon="icon.ico"):
self.url = url
self.icon = icon
第一种方式 - 定义为全局常量
第二种方式 - 定义为类的变量
第三种方式 - 在方法中定义<\ strong>
第4路 - 作为班级常数
答案 1 :(得分:4)
将它们定义为类变量可能是最具前瞻性的方法,因为您稍后可以使用dependency injection来更改这些变量,这对unit testing非常有用。例如:
class Server:
def __init__(self, url, icon):
self.url = url
self.icon = icon
server = Server('url.com', 'file.ico')
# in your tests, you may want to use a different ico/url
test_server = Server('url.com', 'test_icon.ico')
另请注意,Python中应避免使用getter和setter,如果需要验证,则使用properties代替,或者重构具有大量相关代码的类。在Java和C等预编译语言中,getter / setter用于封装,以便以后可以更改实现,但是在Python中避免了性能和清晰度。首先,变量可以正常访问,如果实现发生变化,您可以使用@property
和@variable.setter
装饰器,以便使用getter和setter,即使您似乎正在访问变量直接。
因此,您最初可以直接访问icon
。
print(server.icon)
但是我们稍后会说,您将课程内的icon
重构为_icon_file
和_icon_image
,并在每次设置时加载文件,但应用的其余部分期待icon
变量。这是getters和setter通常用于的(除了设置变量的任何检查/转换),因此我们现在可以为icon
添加getter和setter,即使icon
变量不再存在:
class Server:
def __init__(self, url, icon_filename):
self.url = url
self._icon_filename = icon_filename
self._icon_image = self._load_icon(icon_filename)
@property
def icon(self):
"""
Get the icon file name
@returns str of the icon filename
"""
return self._icon_filename
@icon.setter
def icon(self, icon_filename):
"""
Load a new icon file as the icon
@param icon_filename the relative path to the icon file
"""
if icon_filename[-4:] != '.ico':
raise Exception('Must be of .ico format')
self._icon_filename = icon_filename
self._icon_image = self._load_icon(icon_filename)
def _load_icon(self, icon_filename):
"""
Load a .ico file, and maybe do some other stuff
@returns Image of the loaded icon
@private
"""
# implementation here...
server = Server('url.com', 'file.ico')
print(server.icon) # file.ico
server.icon = 'icon2.ico' # sets and loads new icon
print(server.icon) # icon2.ico
server.icon = 'icon3.jpg' # throws an exception
答案 2 :(得分:2)
您忘记了将它们定义为类级常量的选项:
class Foo(...)
ICON = "xxx"
URL = "YYY"