{"id":402,"date":"2020-04-14T17:44:51","date_gmt":"2020-04-14T08:44:51","guid":{"rendered":"http:\/\/batmask.dothome.co.kr\/?p=402"},"modified":"2025-09-11T18:42:33","modified_gmt":"2025-09-11T09:42:33","slug":"python-%eb%8b%a4%ec%a4%91-%ec%83%81%ec%86%8d%ec%8b%9c-metaclass-%eb%ac%b8%ec%a0%9c","status":"publish","type":"post","link":"http:\/\/batmask.net\/index.php\/2020\/04\/14\/402\/","title":{"rendered":"Python: \ub2e4\uc911 \uc0c1\uc18d\uc2dc, metaclass \ubb38\uc81c"},"content":{"rendered":"\n<p>\ub204\ub204\ud788 \ub9d0\ud558\uc9c0\ub9cc, Python\uc774 OOP \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \uadf8\ub2e4\uc9c0 \uc801\ud569\ud55c \uc5b8\uc5b4\ub294 \uc544\ub2c8\ub2e4. \ub355\ubd84\uc5d0, OOP \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \uc9c0\uc6d0\ud558\uae30 \uc704\ud574 \ub9c8\ub828\ub41c \uc7a5\uce58\ub4e4\uc774 \ucda9\ub3cc\uc744 \uc77c\uc73c\ud0a4\ub294 \uacbd\uc6b0\uac00 \uc885\uc885 \uc788\ub2e4.<\/p>\n\n\n\n<p>\uc624\ub298 \uacaa\uc740 \ubb38\uc81c\ub294 \ub2e4\uc911\uc0c1\uc18d\uc2dc metaclass \ucda9\ub3cc \ubb38\uc81c\ub2e4. \uba3c\uc800 \uac04\ub2e8\ud558\uac8c \ub9d0\ud558\uba74, Python\uc774 \ub2e4\uc911\uc0c1\uc18d\uc744 \uc9c0\uc6d0\ud558\uc9c0\ub9cc metaclass\ub97c \ub2e4\uc911\uc0c1\uc18d \ubc1b\uc744 \uc218\ub294 \uc5c6\ub2e4\ub294 \uc598\uae30\ub2e4. \uc6b0\ud68c\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub294\uac78\ub85c \ubcf4\uc774\uc9c0\ub9cc, \uad73\uc774 \uc774\ub807\uac8c \uae4c\uc9c0 \ud574\uc57c \ud558\ub098\uc2f6\uace0. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-dots\"\/>\n\n\n\n<p>\ubb38\uc81c\uc758 \uadfc\uc6d0\uc778 \uc778\ud130\ud398\uc774\uc2a4\uc5d0 \ub300\ud574 \uba3c\uc800 \ub9d0\ud574\ubcf4\uc790. Python\uc740 duck typing\uc774\ub77c\uace0 \ud574\uc11c \uac19\uc740 \uba54\uc18c\ub4dc\ub97c \uac16\uace0 \uc788\uc73c\uba74 \ub3d9\uc77c\ud558\uac8c \ucde8\uae09\uc774 \uac00\ub2a5\ud558\ub2e4. \ub3d9\uc801\ud0c0\uc785 \uc5b8\uc5b4\uc758 \uc7a5\uc810\uc73c\ub85c \ubcfc \uc218\ub3c4 \uc788\uace0, \uc774 \uc790\uccb4\uac00 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uc5ed\ud560\uc744 \ud558\uae30 \ub54c\ubb38\uc5d0 \uc5b8\uc5b4\ub808\ubca8\uc5d0\uc11c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294\ub2e4.<\/p>\n\n\n\n<p>\uc778\ud130\ud398\uc774\uc2a4\ub294 \uc544\ub2c8\uc9c0\ub9cc \ucd94\uc0c1\ud074\ub798\uc2a4\ub97c \uac04\uc811\uc801\uc73c\ub85c \uc9c0\uc6d0\ud558\ub294\ub370, \ubc14\ub85c abc \ubaa8\ub4c8\uc774\ub2e4. \uc774\ub97c \uc774\uc6a9\ud574 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud560 \uc218 \uc788\ub2e4. abc\ub294 abstract class\ub97c \ub9d0\ud55c\ub2e4. abc\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>from abc import ABCMeta, abstractmethod\n\nclass IObserver(metaclass=ABCMeta):\n    @abstractmethod\n    def data_update(self, msg: str = \"\"):\n        pass\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">from<\/span><span style=\"color: #ADBAC7\"> abc <\/span><span style=\"color: #F47067\">import<\/span><span style=\"color: #ADBAC7\"> ABCMeta, abstractmethod<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">IObserver<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">metaclass<\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #6CB6FF\">ABCMeta<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">@abstractmethod<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">def<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">data_update<\/span><span style=\"color: #ADBAC7\">(self, msg: <\/span><span style=\"color: #6CB6FF\">str<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;&quot;<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #F47067\">pass<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class MainWindow(IObserver):\n    def data_update(self, msg: str = \"\"):\n        print(f\"data update : {msg}\")<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">MainWindow<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">IObserver<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">def<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">data_update<\/span><span style=\"color: #ADBAC7\">(self, msg: <\/span><span style=\"color: #6CB6FF\">str<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;&quot;<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #6CB6FF\">print<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #F47067\">f<\/span><span style=\"color: #96D0FF\">&quot;data update : <\/span><span style=\"color: #F47067\">{<\/span><span style=\"color: #ADBAC7\">msg<\/span><span style=\"color: #F47067\">}<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc704\uc5d0\uc11c \ubcf4\ub4ef\uc774, ABCMeta \ub85c metaclass\ub97c \uc9c0\uc815\ud574\uc11c \ucd94\uc0c1\ud074\ub798\uc2a4\ub97c \ub9cc\ub4e0\ub2e4. \ucd94\uc0c1 \uba54\uc18c\ub4dc\ub294 @abstractmethod \ub97c \ubd99\uc5ec\uc900\ub2e4. concrete class\uc5d0\uc11c \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uace0, \ub3d9\uc77c\ud55c \ud615\ud0dc\uc758 \uba54\uc18c\ub4dc\ub97c \uad6c\ud604\ud574\uc900\ub2e4. \uad6c\ud604\ud558\uc9c0 \uc54a\uc740 \uacbd\uc6b0, \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4.<\/p>\n\n\n\n<p>\uc5ec\uae30\uae4c\uc9c0\ub294 \ub9e4\uc6b0 \ud589\ubcf5\ud55c \uc2dc\ub098\ub9ac\uc624\uc778\ub370, \ub0b4\uac00 \uc4f0\ub294 MainWindow \ud074\ub798\uc2a4\ub294 QMainWindow\ub97c \uc0c1\uc18d\ubc1b\uc544\uc57c \ud55c\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class MainWindow(QMainWindow, IObserver):\n    ...<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">MainWindow<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">QMainWindow<\/span><span style=\"color: #ADBAC7\">, <\/span><span style=\"color: #6CB6FF\">IObserver<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #6CB6FF\">...<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ubb38\uc81c\ub294 Qt\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 metaclass\uc640 ABCMeta \ub450\uac1c\uc758 metaclass\ub97c \uc0ac\uc6a9\ud558\uac8c \ub418\uace0, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>TypeError: metaclass conflict: the metaclass of a derived class must be ...<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6CB6FF\">TypeError<\/span><span style=\"color: #ADBAC7\">: metaclass conflict: the metaclass of a derived <\/span><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> must be <\/span><span style=\"color: #6CB6FF\">...<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ud574\ub2f9 \ubb38\uc81c\ub97c \uc6b0\ud68c\ud558\ub294 \ubc29\ubc95\uc740 \ub450 type\uc744 \ubc1b\ub294 \uc0c8\ub85c\uc6b4 \uba54\ud0c0\ud074\ub798\uc2a4\ub97c \ub9cc\ub4dc\ub294 \uac83\uc774\uc9c0\ub9cc, \uad73\uc774 \uc774\ub807\uac8c\uae4c\uc9c0 \ud574\uc57c\ud558\ub098 \uc0dd\uac01\uc774 \ub4dc\ub294 \uac83. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>from PyQt5.QtGui import QStandardItem\nfrom configparser import ConfigParser\n\nclass FinalMeta(type(QStandardItem), type(ConfigParser)):\n    pass\n\nclass FinalClass(ConfigParser, QStandardItem, metaclass=FinalMeta):\n    def __init__(self, param):\n        ConfigParser.__init__(self)\n        QStandardItem.__init__(self)<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">from<\/span><span style=\"color: #ADBAC7\"> PyQt5.QtGui <\/span><span style=\"color: #F47067\">import<\/span><span style=\"color: #ADBAC7\"> QStandardItem<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">from<\/span><span style=\"color: #ADBAC7\"> configparser <\/span><span style=\"color: #F47067\">import<\/span><span style=\"color: #ADBAC7\"> ConfigParser<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">FinalMeta<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">type<\/span><span style=\"color: #ADBAC7\">(QStandardItem), <\/span><span style=\"color: #6CB6FF\">type<\/span><span style=\"color: #ADBAC7\">(ConfigParser)):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">pass<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">FinalClass<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">ConfigParser<\/span><span style=\"color: #ADBAC7\">, <\/span><span style=\"color: #6CB6FF\">QStandardItem<\/span><span style=\"color: #ADBAC7\">, <\/span><span style=\"color: #6CB6FF\">metaclass<\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #6CB6FF\">FinalMeta<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">def<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">__init__<\/span><span style=\"color: #ADBAC7\">(self, param):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        ConfigParser.<\/span><span style=\"color: #6CB6FF\">__init__<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">self<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        QStandardItem.<\/span><span style=\"color: #6CB6FF\">__init__<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">self<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/28720217\/multiple-inheritance-metaclass-conflict\">https:\/\/stackoverflow.com\/questions\/28720217\/multiple-inheritance-metaclass-conflict<\/a> \ucc38\uc870.<\/p>\n\n\n\n<p>\ub0b4\uac00 \uc120\ud0dd\ud55c \ud574\uacb0\ucc45\uc740 \ud558\ub098\uc758 metaclass\ub9cc \uc0ac\uc6a9\ud558\ub294 \uac83\uc774\ub2e4. abc \ubaa8\ub4c8\uc744 \uc4f0\ub294\uac8c \uac04\ud3b8\ud558\uae34 \ud558\uc9c0\ub9cc, \uad73\uc774 \uc548\uc4f0\uace0\ub3c4 interface\ub97c \uad6c\ud604\ud560 \uc218 \uc788\ub2e4. \uc694\uc810\uc740 interface class\uc5d0\uc11c \uad6c\ud604\ud558\uc9c0 \uc54a\ub418, \uc774\ub97c \uc0c1\uc18d\ubc1b\uc544\uc11c\ub3c4 \uad6c\ud604\ud558\uc9c0 \uc54a\uc73c\uba74 \uc5d0\ub7ec\ub97c \ub0b4\ub294 \uac83\uc774\ub2e4. \uc218\uc815\ud55c IObserver\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class IObserver:\n    def data_update(self, msg: str = \"\"):\n        raise NotImplementedError\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">IObserver<\/span><span style=\"color: #ADBAC7\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">def<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">data_update<\/span><span style=\"color: #ADBAC7\">(self, msg: <\/span><span style=\"color: #6CB6FF\">str<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;&quot;<\/span><span style=\"color: #ADBAC7\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #F47067\">raise<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">NotImplementedError<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ubb38\uc81c \ud574\uacb0! \ud83d\ude42<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-dots\"\/>\n\n\n\n<p>Python\uc5d0\uc11c OOP \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \uacc4\uc18d \ubcbd\uc5d0 \ubd80\ub52a\ud788\uace0 \uc788\ub2e4. \uacf5\ubd80\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uc804\ud600 \uc811\ud558\uc9c0 \uc54a\uc558\ub358 \ubb38\uc81c\ub4e4\uc774\ub2e4. \uc774\uac78 \uc774\ub807\uac8c \uc4f0\ub294\uac8c \uc544\ub2cc\uac00 \uc2f6\uace0, \ubb54\uac00 \ubaa8\uc21c\uc801\uc778 \uac10\uc815\uc744 \ub9ce\uc774 \ub290\ub07c\ub294\uc911.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ub204\ub204\ud788 \ub9d0\ud558\uc9c0\ub9cc, Python\uc774 OOP \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \uadf8\ub2e4\uc9c0 \uc801\ud569\ud55c \uc5b8\uc5b4\ub294 \uc544\ub2c8\ub2e4. \ub355\ubd84\uc5d0, OOP \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \uc9c0\uc6d0\ud558\uae30 \uc704\ud574 \ub9c8\ub828\ub41c \uc7a5\uce58\ub4e4\uc774 \ucda9\ub3cc\uc744 \uc77c\uc73c\ud0a4\ub294 \uacbd\uc6b0\uac00 \uc885\uc885 \uc788\ub2e4. \uc624\ub298 \uacaa\uc740 \ubb38\uc81c\ub294 \ub2e4\uc911\uc0c1\uc18d\uc2dc metaclass \ucda9\ub3cc \ubb38\uc81c\ub2e4. \uba3c\uc800 \uac04\ub2e8\ud558\uac8c \ub9d0\ud558\uba74, Python\uc774 \ub2e4\uc911\uc0c1\uc18d\uc744 \uc9c0\uc6d0\ud558\uc9c0\ub9cc metaclass\ub97c \ub2e4\uc911\uc0c1\uc18d \ubc1b\uc744 \uc218\ub294 \uc5c6\ub2e4\ub294 \uc598\uae30\ub2e4. \uc6b0\ud68c\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub294\uac78\ub85c \ubcf4\uc774\uc9c0\ub9cc, \uad73\uc774 \uc774\ub807\uac8c \uae4c\uc9c0 \ud574\uc57c \ud558\ub098\uc2f6\uace0. \ubb38\uc81c\uc758 <a href=\"http:\/\/batmask.net\/index.php\/2020\/04\/14\/402\/\" class=\"btn btn-link continue-link\">\ub354 \uc77d\uae30<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33],"tags":[122,121,99,116,35,125,124,55],"class_list":["post-402","post","type-post","status-publish","format-standard","hentry","category-python","tag-inheritance","tag-interface","tag-metaclass","tag-oop","tag-python","tag-multiple-inheritance-kr","tag-metaclass-kr","tag-python-kr"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/402","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/comments?post=402"}],"version-history":[{"count":2,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/402\/revisions"}],"predecessor-version":[{"id":3453,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/402\/revisions\/3453"}],"wp:attachment":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/media?parent=402"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/categories?post=402"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/tags?post=402"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}