여러 모듈이 각각 KvLanguage에서 같은 이름의 Widget을 정의할 때 발생하는 일

10872 단어 Kivy
파이썬 자체가 명칭 공간 오염을 막기 위해 프로그램을 모듈화하는 메커니즘을 갖고 있더라도 KvLanguage에서는 그 혜택을 받지 않는다.다음 절차로 검증했습니다.

KvLanguage로 작성된 섹션이 합성됨


다음은 import의 여러 모듈이 KvLanguage에서 같은 이름의 Widget을 정의할 때 확인하는 프로그램입니다.

mywidget_a.py


mywidget_a.py
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout


Builder.load_string(r"""
<MyWidget>:
    Button:
        text: r'mywidget_a'  #
        size_hint: 0.3, 0.1
        pos_hint: {r'center_x': 0.25, r'center_y': 0.5}  #
""")


class MyWidget(FloatLayout):

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        print(r'mywidget_a')  #


if __name__ == r'__main__':
    runTouchApp(MyWidget())
일단 단독으로 집행하면
표준 출력
mywidget_a

mywidget_b.py


mywidget_b.py
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout


Builder.load_string(r"""
<MyWidget>:
    Button:
        text: r'mywidget_b'  #
        size_hint: 0.3, 0.1
        pos_hint: {r'center_x': 0.75, r'center_y': 0.5}  #
""")


class MyWidget(FloatLayout):

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        print(r'mywidget_b')  #


if __name__ == r'__main__':
    runTouchApp(MyWidget())
마찬가지로 단독으로 집행하다
표준 출력
mywidget_b

동시에 import하면...


both.py
from kivy.base import runTouchApp
import mywidget_a
import mywidget_b

runTouchApp(mywidget_b.MyWidget())
표준 출력
mywidget_b

__init__mywidget입니다.b라는 것(기대했던 대로)에 비해 아이 버튼은 mywidgeta의 것까지 만들어 냈다.혹시 모르니까한 번 썼다
Console이라는 도구
틀림없이 합성된 것이다.즉

이렇게


작성을 방지하려면 Widget의 클래스 이름이 프로그램 전체를 덮어쓰지 않도록 주의해야 합니다.
최악의 경우, 모듈 이름을 머리에 적어라, MyWidgetAMyWidget,MyWidgetB_My Widget 느낌을 줄 수 있어요.
어떻게든 해결할 방법 없을까요?

kivy.factory.Factory


보아하니 이 녀석은 KvLanguage에서 위드렛의 생성과 관련이 있는 것 같다.실제로 사용해 보세요.
먼저 both.py는 다음과 같이 쓸 수 있다.
both.py
from kivy.base import runTouchApp
from kivy.factory import Factory
import mywidget_a
import mywidget_b

runTouchApp(Factory.MyWidget())
표준 출력
mywidget_a
또한, mywidgeta.py는 다음과 같이 쓸 수 있다.
mywidget_a.py
from kivy.base import runTouchApp
from kivy.factory import Factory


class MyWidget(Factory.FloatLayout):

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        button = Factory.Button(
            text=r'mywidget_a',
            size_hint=[0.3, 0.1],
            pos_hint={r'center_x': 0.25, r'center_y': 0.5})
        self.add_widget(button)
        print(r'mywidget_a')

if __name__ == r'__main__':
    runTouchApp(Factory.MyWidget())
딱 봐도 버튼과 FlatLayout은 어떤 import도 사용하지 않아도 된다.일반적으로 말하면
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
이렇게 이용하는 물건이니까.KvLanguage 내에서 이용할 수 있는 다른 것들은 거의 팩토리부터 이용할 수 있다.이 [Package 이름과 모델 이름의 불필요한 편의성]의 대가로 [다른 모델의 Widget 이름과 충돌하는 수고에 주의해야 함]을 지불할 수 있을까요?어쨌든 이름이 가려져도 아무 말도 안 하고 귀찮아요.

어떻게 이름 충돌을 피합니까


팩토리에는 unregister라는 Method가 있는데, 처음에는 이렇게 하면 합성을 피할 수 있다고 생각했지만 다르다.
both.py
from kivy.base import runTouchApp
from kivy.factory import Factory
import mywidget_a
Factory.unregister(r'MyWidget')  # mywidget_aのMyWidgetを登録解除?
import mywidget_b

runTouchApp(Factory.MyWidget())
표준 출력
mywidget_b

그래서 해결하지 못했어.

좋은 웹페이지 즐겨찾기