使功能结构稍微高效一些



我有一堆灯光试图控制。与其让每个按钮状态更改调用一个唯一的函数,我想尝试拥有一个多用途函数,因为这就是函数的用途(据我所知)。

按钮调用功能:

ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKS1(1)

该函数:

def changeKS1(self,change):
if change==1 and b.get_light(1, 'on'):
self.KitchenSpot1(False)
else:
self.KitchenSpot1(True)

然后,该函数调用此函数以使用第 3 部分库物理更改光源的状态。

def KitchenSpot1(self,state):
lights[0].name
lights[0].on = state

我在函数内部传递"1"的原因是因为它不喜欢在其中传递任何内容(我不知道为什么它不喜欢它)。如果你还没有猜到,我是新手。我有一点 cpp 微控制器背景,但我正在尝试了解基于 python 和 PC 的编程。我正在寻找一些关于如何最好地压缩它并使其尽可能高效的建议。我可能对python了解不多,但是,我知道我不应该把几乎相同的东西输入30次。

提前感谢任何可以分享他们智慧的人。

值得注意的是,我正在使用带有 python 的 kivy 来生成按钮。

完整 main.py 代码:

from kivy.properties import StringProperty
import kivy
from kivy.uix.togglebutton import ToggleButton
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.app import App
kivy.require('1.10.0')
from phue import Bridge
import nest
b = Bridge('xx.xxx.xxx.xxx')
b.connect()
b.get_api()
lights = b.lights
class Controller(GridLayout):
state = StringProperty('down')
def __init__(self, **kwargs):
super(Controller, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def KitchenSpot1(self,state):
lights[0].name
lights[0].on = state
def changeKS1(self,change):
if change==1 and b.get_light(1, 'on'):
self.KitchenSpot1(False)
else:
self.KitchenSpot1(True)

def KitchenSpot2(self,state):
lights[1].name
lights[1].on = state
def KitchenSpot3(self,state):
lights[2].name
lights[2].on = state
def OfficeSpot1(self,state):
lights[3].name
lights[3].on = state
def OfficeSpot2(self,state):
lights[4].name
lights[4].on = state
def OfficeSpot3(self,state):
lights[5].name
lights[5].on = state
def OfficeSpot4(self,state):
lights[6].name
lights[6].on = state
def JuliaBedside(self,state):
lights[7].name
lights[7].on = state
def JohnBedside(self,state):
lights[8].name
lights[8].on = state


def update(self, dt):
if b.get_light(1, 'on'):
self.state = 'down'
else:
self.state = 'normal'

class ActionApp(App):
def build(self):
return Controller()

if __name__ == "__main__":
myApp = ActionApp()
myApp.run()

完整操作.kv 代码

<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"                                      
ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKS1(1)
#on_release: root.KitchenSpot1(False)
#state1 = app.update.h
state: root.state

ToggleButton:
text: "Kitchen Spot 2"
Button:
text: "Kitchen Spot 3"
Button:
text: "Kitchen Spot 4"
Button:
text: "Office Spot 1"
Button:
text: "Office Spot 2"
Button:
text: "Office Spot 3"
Button:
text: "Office Spot 4"

更新: 蟒蛇程序:

def lightcontrol(self,lightnumber):
if b.get_light(1, 'on'):
lights[lightnumber].name
lights[lightnumber].on (False)
#self.KitchenSpot1(False)
else:
lights[lightnumber].name
lights[lightnumber].on (True)
#self.KitchenSpot1(True)

基维按钮:

ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.lightcontrol(0)

让每个按钮调用相同的函数,但使用不同的参数。

# Add the a number parameter here based on what you've
def KitchenSpot(self,state, light_index):
lights[light_index].name
lights[light_index].on = state

然后在 KV 文件中,

Button:
text: "Kitchen Spot 3"
on_press: root.KitchenSpot(state, light_index = 3)
Button:
text: "Kitchen Spot 4"
on_press: root.KitchenSpot(state, light_index = 4)

您只需创建一个函数,每个按钮都会传入相关的light_index编号。

既不知道 kivy 也不了解 phue,我试图通过抽象方法的定义(以及创建action.kv文件)将问题减少到您的代码冗余。

所以我希望这是你正在寻找的:首先,我将在全局变量中定义按钮的所有相关数据,例如:

BUTTONS = [
{'id': 0, 'methodname': 'KitchenSpot1', 'text': 'Kitchen Spot 1'},
{'id': 1, 'methodname': 'KitchenSpot2', 'text': 'Kitchen Spot 2'},
...
]

然后像你一样用所有独特的方法定义你的控制器类(在你的例子中__init__update;但是我没有看到更新应该做什么,我只是让它保持原样):

class Controller(GridLayout):
state = StringProperty('down')
def __init__(self, **kwargs):
super(Controller, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def update(self, dt):
if b.get_light(1, 'on'):
self.state = 'down'
else:
self.state = 'normal'
# this iteratively creates your button-individual methods
for button_dict in BUTTONS:        
def func(self, state):
lights[button_dict['id']].name   # whatever this might do just adressing the name attribute. Is it a python-property on lights that does some action?
lights[button_dict['id']].on = state
def func_change(self, change):
if change == True and b.get_light(button_dict['id'], 'on'):
getattr(self, button_dict['methodname'])(False)
else:
getattr(self, button_dict['methodname'])(True)
# create .KitchenSpot1, .KitchenSpot2, ...
setattr(Controller, button_dict['methodname'], func)
# create .changeKitchenSpot1, .changeKitchenSpot2, ...
setattr(Controller, "change{}".format(button_dict['methodname']), func_change)

实例化的控制器将具有绑定方法,这些方法对应于所有方法名和更改方法名。

最后,您可以动态创建action.kv文件

actionkv_toggle_button = """    
ToggleButton:
id: {methodname}Toggle
text: "{text}"
on_press: root.change{methodname}(1)
#on_release: root.{methodname}(False)
#state1 = app.update.h
state: root.state
"""
actionkv_str = """
<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"
{buttons}
""".format(
buttons="".join([
actionkv_toggle_button.format(
methodname=button_dict['methodname'],
text=button_dict['text']
) for button_dict in BUTTONS
])
)

这给出了输出

<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"

ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKitchenSpot1(1)
#on_release: root.KitchenSpot1(False)
#state1 = app.update.h
state: root.state
ToggleButton:
id: KitchenSpot2Toggle
text: "Kitchen Spot 2"
on_press: root.changeKitchenSpot2(1)
#on_release: root.KitchenSpot2(False)
#state1 = app.update.h
state: root.state

将其保存到文件

with open('action.kv', 'w') as f:
f.write(actionkv_str)

有用的链接:

将方法动态附加到类

python中的字符串格式

列表理解

最新更新