英文:
i have a problem with using __getattribute__
问题
这是你的代码,出现了AttributeError错误:
File "c:\Users\User\Desktop\python\book2\unit2\project6.py", line 25, in <module>
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\User\Desktop\python\book2\unit2\project6.py", line 13, in __init__
self.lst.append(L[i])
^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'append
错误的原因是在构造函数中,你尝试将字符串追加到一个字符串属性self.lst
上,这是不合法的。你应该将它追加到self.txt
,因为你的目标是构建一个包含字符串首字母的文本。
你可以将这一行:
self.lst.append(L[i])
更改为:
self.txt += L[i][0]
这应该能解决你的问题。
英文:
I have a school task that i need to do. I should create an object when constructor where when you put a list as an argument it only takes the string from the list and put them in the attribute of the class. When you try to print the list, it should only print the first characters of each string in the list. For example, if i put [1,2,3,4,"something","word"]
the attribute should contain ["something","word"]
and when you print it on the console it should pop up sw. I must use __getattribute__
.
This is the code that I wrote
class Myclass:
def __init__(self, L):
self.lst = []
self.txt = ""
if type(L) == list:
for i in range(len(L)):
if type(L[i]) == str:
self.lst.append(L[i])
for i in range(len(self.lst)):
self.txt += self.lst[i][0]
def __getattribute__(self, name):
if name == "lst":
return object.__getattribute__(self, "txt")
else:
return object.__getattribute__(self, name)
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
print(objA.lst)
print(objA.txt)
it gives me AttribureError:
File "c:\Users\User\Desktop\python\book2\unit2\project6.py", line 25, in <module>
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\User\Desktop\python\book2\unit2\project6.py", line 13, in __init__
self.lst.append(L[i])
^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'append
答案1
得分: 1
I made attribute private. __getattribute__
method is used in both cases: creating object and accessing by print(objA.lst)
.
在创建对象时,self._lst.append(item)
调用了 __getattribute__
方法。类似于 self.__getattribute__('_lst')
class Myclass:
def __init__(self, L):
self._lst = [] # 用于保存字符串列表的私有属性
self.txt = ""
if isinstance(L, list):
for item in L:
if isinstance(item, str):
self._lst.append(item)
self.txt += item[0]
def __getattribute__(self, name):
if name == "lst":
return object.__getattribute__(self, "txt")
else:
return object.__getattribute__(self, name)
if __name__ == '__main__':
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
print(objA.lst) # 输出 'sw'
英文:
I made attribute private. __getattribute__
method is used in both cases: creating object and accessing by print(objA.lst)
.
In the case of creating object, self._lst.append(item)
calls __getattribute__
under the hood. Like self.__getattribute__('_lst')
class Myclass:
def __init__(self, L):
self._lst = [] # private attribute to hold the list of strings
self.txt = ""
if isinstance(L, list):
for item in L:
if isinstance(item, str):
self._lst.append(item)
self.txt += item[0]
def __getattribute__(self, name):
if name == "lst":
return object.__getattribute__(self, "txt")
else:
return object.__getattribute__(self, name)
if __name__ == '__main__':
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
print(objA.lst) # prints 'sw'
答案2
得分: 1
没有必要在列表上使用range
,只需枚举列表。如下所示:
class Myclass():
def __init__(self, L):
self.txt = ""
if type(L) == list:
for s in L:
if type(s) == str:
self.txt += s[0:1]
def __getattribute__(self, name):
if name == "lst":
return object.__getattribute__(self, "txt")
else:
return object.__getattribute__(self, name)
objA = Myclass([1, 2, 3, 4, 5, "something", "word", ""])
print(objA.lst)
print(objA.txt)
英文:
There is no need to use range on lists, just enumerate the list. As follows:
class Myclass():
def __init__(self, L):
self.txt = ""
if type(L) == list:
for s in L:
if type(s) == str:
self.txt += s[0:1]
def __getattribute__(self, name):
if name == "lst":
return object.__getattribute__(self, "txt")
else:
return object.__getattribute__(self, name)
objA = Myclass([1, 2, 3, 4, 5, "something", "word", ""])
print(objA.lst)
print(objA.txt)
答案3
得分: 0
I believe you have solved this in reverse. You do not need to construct the "txt" attribute, because that's exactly how lists print themselves. Consider:
class Myclass:
def __init__(self, L):
self.lst = []
if type(L) == list:
for i in L:
if type(i) == str:
self.lst.append(i)
def __getattribute__(self, name):
if name == "txt":
lst = object.__getattribute__(self, "lst")
return ''.join(l[0] for l in lst)
else:
return object.__getattribute__(self, name)
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
print(objA.lst)
print(objA.txt)
Output:
['something', 'word']
sw
Note that your design doesn't work if you add to lst
later, whereas this design will.
英文:
I believe you have solved this in reverse. You do not need to construct the "txt" attribute, because that's exactly how lists print themselves. Consider:
class Myclass:
def __init__(self, L):
self.lst = []
if type(L) == list:
for i in L:
if type(i) == str:
self.lst.append(i)
def __getattribute__(self, name):
if name == "txt":
lst = object.__getattribute__(self, "lst")
return ''.join(l[0] for l in lst)
else:
return object.__getattribute__(self, name)
objA = Myclass([1, 2, 3, 4, 5, "something", "word"])
print(objA.lst)
print(objA.txt)
Output:
['something', 'word']
sw
Note that your design doesn't work if you add to lst
later, whereas this design will.
答案4
得分: 0
在我看来,实现这个的最优雅和可读性最好的方式是通过重写collections UserList的初始化方法以及负责添加元素的所有方法,以及用于获取列表的方法,只返回第一个字母。
英文:
In my opinion most elegant and readable way to accomplish that is by overriding collections UserList init and all methods that takes care of adding elements + the one for getting list to only return first letters.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论