class A:
class B(A):
pass
#//////////////////////////////////////
Traceback (most recent call last):
File ".\test.py", line 1, in <module>
class A:
File ".\test.py", line 2, in A
class B(A):
^
NameError: name 'A' is not defined
如果是類似super的方法我應該沒辦法用
因為我其實要用的地方是
class Config:
class default:
class language:
#code
class first_online:
class language(Config.default.language):
#code
大概是這種感覺
這是有辦法的嗎?
或是直接就是不可能?
先不管你想做什麼, 純粹語法上來說, 錯誤訊息已經告訴你不可行:
>>> class A:
... class B(A):
... pass
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in A
NameError: name 'A' is not defined
因為定義 B 的時候, A 還沒有完整定義, 所以錯誤訊息告訴你 A 尚未定義。
謝謝原來是這樣!!
那我知道了不行的原因了
不過這樣我就有新的疑問(這人問題好多XD)
class A:
class B1:
pass
class B2:
class C(B1):#or class C(A.B1):
pass
這樣的狀況A底下的B1不是已經被完整定義了嗎?
怎麼還是不行?
一樣作用域的問題。你這樣寫和你原本寫的不是一樣嗎?就往下移一層而已。
雖然不知道為甚麼
不過好像是不行的
因為 B1 是 A 的屬性, 所以你要寫 A.B1 才能存取到 B1 的定義, 單獨寫 B1 就會是沒有定義的名稱, 所以會說 B1 未定義。這可以透過底下的例子說明:
>>> class A:
... class B1:
... pass
... def foo(self):
... print(B1)
... def foo1(self):
... print(A.B1)
>>> a1 = A()
>>> a1.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in foo
NameError: name 'B1' is not defined
>>> a1.foo1()
<class '__main__.A.B1'>
但如果要在 A 的定義內使用 A.B1, 就遇到同樣的問題了, 在定義 C2 的這一行時, A 還是沒有定義完成, 所以它會說 A 未定義。
如果你是在 A 中的函式定義新類別, 那就沒問題了, 例如:
>>> class A:
... class B1:
... pass
... def foo(self):
... class C1(A.B1):
... pass
... return C1()
>>> a1 = A()
>>> c1 = a1.foo()
>>> type(c1)
<class '__main__.A.foo.<locals>.C1'>
雖然定義 C1 的程式碼也是寫在 A 內, 但是實際定義的動作是發生在 foo 執行時, 而這一定是 A 已經定義完成後才會生的事。
非常感謝你的回覆
我還以為真的沒有任何方法已經算是放棄了
之前別人回復我是以A當作藍圖做舉例
其實我一直有疑問為甚麼不能在圖紙之中分割一個小區域
用作描述其他部分會使用到的公用部件,如B1
也就是藍圖內又有小藍圖XD
目前看起來是因為我少了一個定義的動作
類比的話就好像我沒有在藍圖內劃定範圍
這樣就導致閱讀的人(電腦)以為是一個整體
你說的方法我回頭會再試試,謝謝你的幫助
現在我又學到了一課,謝謝你
其實我一直有疑問為甚麼不能在圖紙之中分割一個小區域
用作描述其他部分會使用到的公用部件,如B1
誰說不可以,可以啊,問題是部件和本體不會相同,你吹風機裡面電熱絲會和吹風機一樣一個類嗎?哪怎麼會用到繼承?
我一直在跟你說class in class會用到的大部分是封裝,但你想要用的用法是繼承,這就很有問題了。
另外藍圖通常會都畫完,放在那邊,要生產的時候再取用(實例化)。實例化的時候才會比較有判斷是去操作。
不太會有哪種需要判斷哪種藍圖什麼時候開始畫的狀況。
來,這是linebot的message的類,你自己看看人家code怎麼寫的,和你的差多少?人家的一樣用到繼承有和你一樣一層一層class嗎?
https://github.com/line/line-bot-sdk-python/blob/master/linebot/models/messages.py
然後一直跟你說,直接把config的格式完整寫一個範例,就會有人幫你生個code了...
class 不是這樣玩的...說真的看不懂你為何要這樣設計。
class ConfigSetting:
...
class Config:
def __init__(self, default:ConfigSetting, settings:ConfigSetting ):
self.default = default
self.settings =settings
default = ConfigSetting(....)
settings = ConfigSetting(....)
config = Config(default=default, settings=settings)
# 照你的格式去寫的,雖然我對你Config裡面還要塞莫名其妙的同類東西感到不解,命名也很奇怪。
這樣不是很好嗎?
在class裡面寫class通常是為了封裝,不是為了繼承。
如果你是要做類似節點這種樹狀結構的話,也用不到繼承。
default是打算放在那邊
當我其他地方有用到的時候就從那裏叫出
比如我需要用到language底下的東西時
我希望直接class language(default.language):就好
如果有需要添加或修改後續再添加或修改
然後因為我是打算用Config直接封裝全部所以這樣寫
大概邏輯是
__ 牛角麵包
___ 麵包類--|__ 波羅麵包
___ 袋子裡有的 - | __ 蘋果牛奶
一個袋子 - | (default) |___ 牛奶類--|__ 木瓜牛奶
(Config) |
|___ 肚子餓了想吃 -- 袋子裡的麵包
| (first_online) (Config.default.麵包類)
|___ 嘴巴渴了想喝 -- 袋子裡的牛奶
(Config.default.牛奶類)
當然我也可以兩個袋子
一個專門裝已經有的
一個裝之後的會觸發的事件
而且事實上我目前就是這麼做
__ 牛角麵包
___ 麵包類--|__ 波羅麵包
袋子裡有的 - | __ 蘋果牛奶
(default) |___ 牛奶類--|__ 木瓜牛奶
-----------------------------------------------
___ 肚子餓了想吃 -- 袋子裡的麵包
一個袋子 - | (first_online) (default.麵包類)
(Config) |___ 嘴巴渴了想喝 -- 袋子裡的牛奶
(default.牛奶類)
但說實話我還是想整個收在Config裡
比較乾淨XD
你把default直接定在class內就好,某個物件專用的config檔通常也不會拿來通用,default直接綁死在class內就好。
class ConfigSettings:
def __init__(self, lang):
self.lang = lang if lang is not None else "zh-TW"
class Config:
def __init__(self, settings:ConfigSettings):
self.setting = settings
其實default直接寫在Config裡面就好。ConfigSettings那根本是不必要的拆分,除非有特殊設計。
你原本那樣寫根本無視了作用域,就算作用域讓你可以進行這樣的操作,也還有無限繼承樹的問題。
我大致知道了
本來我的想法是
class Config:
class default:
class language:
#code
class page2:
#code
class first_oneline:
class language(default.language):
#code
class page2(default.page2):
#code
class ......:
class ......(default. ......)
class ......(default. ......)
其實default直接寫在Config裡面就好。
我理解到的意思是
class Config:
class default:
#code
class first_oneline(default):
#code
雖然不知道對不對
但如果我是這樣寫我代碼可能就要變成底下兩種
class Config:
class default:
class language:
#code
class page2:
#code
class page3:
#code
# 這裡是first_oneline
class language(default.language):
#code
class page2(default.page2):
#code
class page3(default.page3):
#code
# 這裡是(其他分類)
class ......(default. ......)
class ......(default. ......)
class Config:
class default:
class language:
#code
class page2:
#code
class page3:
#code
if '這裡是first_oneline' != 0:
class language(default.language):
#code
class page2(default.page2):
#code
class page3(default.page3):
#code
if '這裡是(其他分類)' != 0:
class ......(default. ......)
class ......(default. ......)
好吧,也不是不行,就這樣做好了XD
這樣好像也可以XDDD
那不過我還有一個問題一直想不明白
class B1:
def __init__(self,setting=None):
self.setting=setting if setting is not None else 'No setting'
class B2:
class C:
def __init__(self, B1=B1):
self.reset=B1().setting
print(B2.C().reset)
#-------------------------------------------------
No setting
#-------------------------------------------------
上面的狀況是分開放
這種狀況是可以繼承的
但是下面這樣,把兩個放一起就不行了?
class A:
class B1:
def __init__(self,setting=None):
self.setting=setting if setting is not None else 'No setting'
class B2:
class C:
def __init__(self, B1=A.B1):
self.reset=B1().setting
print(A.B2.C().reset)
#-------------------------------------------------
A未定義
#-------------------------------------------------
class A:
class B1:
def __init__(self,setting=None):
self.setting=setting if setting is not None else 'No setting'
class B2:
class C:
def __init__(self, B1=B1):
self.reset=B1().setting
print(A.B2.C().reset)
#-------------------------------------------------
B1未定義
#-------------------------------------------------
在我的觀念中
C應該是要繼承B1
也確實不在同一個class裡時 是這樣的沒錯
但是當我把全部放在A中時
C卻沒辦法繼承A底下的B1
雖然你說這樣會有無限繼承樹的問題
可是我不太懂
如果我今天是直接C繼承A
那確實會變成
C繼承A
以及A底下的B1、B2以及C與C繼承的A
以及A底下的B1、B2以及C與C繼承的A
以及A底下的B1、B2以及C與C繼承的A......
到這裡為止我理解(或是我有誤解XDD)
那為甚麼不能C繼承A的B1
難道他是C同時繼承A以及B1嗎?
但我在class外用A.B1繼承的時候
沒辦法呼叫A底下的其他東西呀?
這是有甚麼原因嗎?
我是在哪一個地方有誤解的?
真的沒有任何方法可以讓C繼承B1嗎?
...
class是類別,你把它當實例用。
好的,我知道了
讓我消化一下XD
反正最簡單就是
沒任何方法可以放default.lang在first.lang()的括號中對吧?
...
你類別的用法錯的一踏糊塗,建議重新看看到底該怎麼用。
另外建議重開一篇,去敘述你需要的,直接寫給你看會比較好,而不是用你錯誤的理解去繞...
然後建議多去看看github,去看看別人的專案原始碼是怎麼寫的。
https://github.com/line/line-bot-sdk-python
我個人建議line-bot可以好好看一看,不大
好的我知道了
我會去看的
順一說
我差不多只是把class拿來當分類分組的東西XD
因為本來一開始是以為class是組別的意思
像是一個大團體可以分成好多小團
現在知道不完全是了XD
你把class當成藍圖就行了,譬如你是個ODM,自己生產吹風機,也要幫A、B牌設計並生產吹風機。
# 設計階段(類別)
class Dryer:
def __init__(self):
self.input_volt = 110
self.watt = 1500
# A牌有負離子功能
class A_Dryer(Dryer):
def __init__(self):
super().__init__()
self.ions = True
# B牌電壓220
class B_Dryer(Dryer):
def __init__(self):
super().__init__()
self.input_volt = 220
# 生產階段(實例)
m = Dryer()
a = A_Dryer()
print(a.ions)
b = B_Dryer()
print(b.input_volt)
子項在實例化時會用super()去得到母項,然後去調用魔術方法 init()
去生成母項 init() 裡的所有項目,後面再擴充(A牌)或是覆蓋(B牌)的屬性
繼承是這樣用的,不是像你那樣亂來...
原來是這樣!
我本來試想的是如果可以就把上面三個class用大class包起來
現在我懂你的意思了!!
藍圖還沒完稿就想使用當然是不行
如果硬要使用就只能在畫一個小藍圖在旁邊
完全懂了!!!
看來包起來要用if (被打W
if '這裡是吹風機' != 0:
class......
class......
# 因為這樣在軟體中才可以摺起來,太多行找不到XD
# 也就是說 if 是用來佔位子的XD
ㄜ...我覺得你還是沒懂。需求寫出來寫清楚,別人寫給你看比較好。
基本上我覺得依你目前說的來看,就是需要dataclass而已。
dataclass可以直接指定預設值,可以驗證資料類型,甚至可以驗證資料是不是符合定義,譬如一定是正數,在5~100之間
需求寫出來寫清楚
我只是想要摺起來XD
摺在一行裡W
最一開始那樣問是因為不想用if做廢行
if的方法我已經會了,我想學別的我不會的
所以if 'XXXXXX' != 0:單純只是為了做標籤
本來:
後來:
阿對,既然都提到了,可以解釋一下dataclass嗎?
我查到的好像是類似
定義:資料類型
比如:
class XXX:
coint:int
這種的話我可能用不了?
就以Lang就好
我的class Default.language底下就已經有很多看起來沒辦法的了
Pass = #True or False
if Pass:
pass
else:#這裡是最外層了再往外是判斷是否跳過所有
if 'class Default' == 0:
class Default
class Buttons:#跳過
class language(View,Select):
def __init__(self):
super().__init__()
variable={}
exec(open_file,globals(),variable)
lang = variable.get('lang')
options=[]
for language in os.listdir('cmds/rpg_define'):
if language.endswith('lang'):
with open(f'cmds/rpg_define/{language}','r',encoding='utf-8') as Lang_file:
for line in Lang_file:
if line.strip().startswith('language-Type'):
line = line.strip().split('=',1)[1]
options.append(SelectOption(label=line,value=language[:-5]))
options = Select(placeholder=f'{eval(lang.get('language','"rerror402"'))}...',options=options)
options.callback = self.options_callback
self.add_item(options)
decided = Default.Buttons.decided()
decided.callback = self.decided_callback
self.add_item(decided)
back = Default.Buttons.back()
back.callback = self.back_callback
self.add_item(back)
#下面還有但跳過,只有範例
async def back_callback(self, interaction: discord.Interaction):
await interaction.response.edit_message(content=None,embed=embed,view=Interface_Config.first_online.Player_Guidelines())
#上面還有但跳過,只有範例
class Race(View,Select):
def __init__(self):
super().__init__()
pass#還沒寫
#class Default只到這
if 'class Interface_Config' == 0:
class Interface_Config:
class first_online:
class language(Default.language):
pass#我真的只打pass
class Race(Default.Race):#預計,還沒寫
pass#我真的只打pass
class setting:
class language(Default.language):
pass#我真的只打pass
class Race(Default.Race):#預計,還沒寫
pass#我真的只打pass
#class Interface_Config只到這
感覺你一直想讓我丟出來
比較好判斷我到底要做甚麼XD
不過就是不想丟這個
因為會自動換行,我怕我每次回來看都要花時間找XD
我只能說你這根本就是亂寫...沒人這樣用class的。
前面就說過了,class是藍圖,沒人有辦法對藍圖進行操作。
要進行操作的會是實例。