base.ImportV1也太難用了吧...
要記得start、build跟finish的順序,又要記得所產生的Entities只能在build跟finish間取得。
有沒有辦法改寫一下code,給二次開發的兄弟們,一個比較好的使用體驗呢?
是滴!諸位的心聲我們都聽到了,下面就不藏私地跟大家分享我們的解法。
class-based的Context Manager,取名為MyImportV1的class。_attrs的class variable,其型態為tuple,裡面儲存的三個element,是我們之後想取得的Entity。__init__中建立一個self.a,是一個base.ImportV1的instance。__enter__中,呼叫self.a.start,並return self.a。這一步可謂是關鍵,這邊return的object,會被當作with ooo as xxx中的xxx,也就是我們在Context Manager中,真正會使用的 object。大部分的Context Manager會在這邊return self,但我們想於Context Manager中借助base.ImportV1,所以必須return self.a。__enter__,先呼叫self.a.build,並於最後呼叫self.a.finish。在build及finish之間,就是我們可以動手腳的地方,因為我們只能在此取得產生的Entity。我們針對self._attrs打一個迴圈,透過getattr(self.a, _attr)得到所產生的Entity,再透過setattr(self, _attr, attr),將這些Entity各自存為一個instance variable。如此一來,於主程式中我們就能透過MyImportV1的instance來取得這些Entity了。# ctxmgr.py
from ansa import base
class MyImportV1:
_attrs = ('nodes', 'shells', 'solids')
def __init__(self):
self.a = base.ImportV1()
def __enter__(self):
self.a.start()
return self.a
def __exit__(self, exc_type, exc_value, exc_tb):
self.a.build()
for _attr in self._attrs:
attr = getattr(self.a, _attr)
setattr(self, _attr, attr)
self.a.finish()
經過一番乾坤大挪移後:
start、build跟finish了。plate_import_v1及box_import_v1可以於Context Manager的範圍外,取得node、shells及solids了。# box_drop.py
def main():
deck = constants.LSDYNA
set_deck_to(deck)
# plate
plate_prop = create_sec()
plate_mat_prop_id = plate_prop._id
plate_set = create_set(plate_prop, 'plate', deck=deck)
l_p, w_p, en1_p, en2_p = 100, 100, 10, 10
z_elv_p, move_xy_p, rot_angle_p = 0, None, None
plate_import_v1 = MyImportV1()
with plate_import_v1 as import_v1:
create_plate_v1(import_v1,
l_p,
w_p,
en1_p,
en2_p,
plate_mat_prop_id,
z_elv=z_elv_p,
move_xy=move_xy_p,
rot_angle=rot_angle_p,
deck=deck)
plate_nodes = plate_import_v1.nodes
plate_shells = plate_import_v1.shells
# box
box_prop = create_sec(sec_type=SecType.SECTION_SOLID)
box_mat_prop_id = box_prop._id
box_set = create_set(box_prop, 'box', deck=deck)
l_b, w_b, h_b, en1_b, en2_b, en3_b = 50, 50, 50, 10, 10, 10
z_elv_b, move_xy_b, rot_angle_b = 5, (50, 20), 45
box_import_v1 = MyImportV1()
with box_import_v1 as import_v1:
create_box_v1(import_v1,
l_b,
w_b,
h_b,
en1_b,
en2_b,
en3_b,
box_mat_prop_id,
z_elv=z_elv_b,
move_xy=move_xy_b,
rot_angle=rot_angle_b,
deck=deck)
box_nodes = box_import_v1.nodes
box_solids = box_import_v1.solids
[Day18]我們準備暫時抽離這不斷精進,不斷改code的十天,來寫點tests吧!