编辑引用类列表的属性

时间:2014-01-06 16:25:22

标签: python python-3.x

我很久以前就开始了这个小项目,但是我已经深入了解它;每当我尝试在列表中引用我的班级实例时,都会显示AttributeError: 'str' has no attribute 'lista'。在这种情况下它唯一的lista因为我只是试图创建1个列表,lista,这里是代码,它有点冗长。拥有所有代码将允许您完全掌握并分析任何(甚至很多,我已经知道我的if-else格式;我喜欢它简单):

class UserInput:
    users=[]

    def __init__(self, name,lista,listb,listc,listd):
        self.name=""
        self.lista=lista
        self.listb=listb
        self.listc=listc
        self.listd=listd

    @classmethod                    #the @classmethod is  a preference for later sub-classes to have the ability to edit the list if need-be
    def create_new_users(cls):
        print("how many users do you want to create")
        x=int(input())
        for _ in range(x):       
            print("assign the users names")
            name = input()
            if name == '' or name.lower()  == 'none':
                raise RuntimeError("name cannot be None or empty")              
            name=cls(name,lista="",listb="",listc="",listd="")
            cls.users.append(name)
        return(name)

    @classmethod  
    def show_users(cls):
        print(UserInput.users)

    @classmethod    
    def set_lists(cls):
        print("Do you want to create lists")
        decision = input()
        print( "select the user you intend on adding lists for")

        namestring = input()             
        for elem in UserInput.users:
            print(vars(UserInput.users[0]))                      
            if decision == "yes":   
                print("how many lists would you like to create?(up to 4)")
                decision2= int(input())
                if decision2 == 1:
                    print("what would you like the list to be named?")
                    setattr(UserInput.users[0],'lista',+ namestring)                            
                else:
                     return

            else:
                 return

我的问题:这一行,print(vars(UserInput.users[0]))清楚地表明对象的引用是空的,为什么不允许我编辑对象(对于为了测试这个,如果你这样做,输入一个用户和一个列表)即使有UserInput.users[0]对象的CLEAR引用?顺便说一句,当我只输入一个用户时,由于其用户[0]主要用于测试目的以使其工作,它确实返回对象所持有的内容,vars()函数执行该操作

应用代码:

    from user import UserInput
UserInput.create_new_users()
print(vars(UserInput.users[0]))
UserInput.set_lists()

导致

how many users do you want to create
1
assign the users names
tim
{'name': '', 'listb': '', 'lista': '', 'listd': '', 'listc': ''}
Do you want to create lists
yes
select the user you intend on adding lists for
tim
{'name': '', 'listb': '', 'lista': '', 'listd': '', 'listc': ''}
how many lists would you like to create?(up to 4)
1
what would you like the list to be named?
hello
Traceback (most recent call last):
  File ".\test.py", line 4, in <module>
    UserInput.set_lists()
  File "C:\Users\Tim\desktop\project ideas\user.py", line 41, in set_lists
    setattr(UserInput.users[0].lista,'UserInput.users[0].lista', namestring)
AttributeError: 'str' object has no attribute 'UserInput.users[0].lista'

{'name': '', 'listb': '', 'lista': '', 'listd': '', 'listc': ''} = vars(UserInput.users[0])

1 个答案:

答案 0 :(得分:1)

使用Python 3.3运行我编辑的代码并将注释添加到:

class User:  # changed class name to make it clearer
    users = {}

    def __init__(self, name, list_a, list_b, list_c, list_d):  # added underscores to make list name easier to read
        self.name = name
        self.list_a = list_a
        self.list_b = list_b
        self.list_c = list_c
        self.list_d = list_d

    @classmethod  # the @classmethod is a preference for later sub-classes to have the ability to edit the list if need-be
    def create_new_users(cls):
        print("how many users do you want to create")
        x = int(input())
        for _ in range(x):
            name = input("Assign the users names")
            if name == '' or name.lower() == 'none':
                raise RuntimeError("name cannot be None or empty")
            new_user = cls(name, list_a=[], list_b=[], list_c=[], list_d=[])  # changed strings to lists
            cls.users[new_user.name] = new_user  # adds new_user to the dict using the user name as the key

    @classmethod
    def show_users(cls):
        for key in cls.users:
            print(key, cls.users[key])

    @classmethod
    def set_lists(cls):
        choice = input("select the user you intend on adding lists for")  # moved prompts into input()
        for elem in User.users:
            print(vars(User.users[choice]))
            decision2 = int(input("how many lists would you like to create?(up to 4)"))
            if decision2 == 1:
                name_string = input("what would you like the list to be named?")
                setattr(User.users['Ian'], 'list_a', name_string) # see below
                print("you have created 1 list, with the name:%s" %name_string)

在shell中运行时产生这个

>>> usr.create_new_users()
how many users do you want to create? 

1
Assign the users names: Ian
>>> print(vars(User.users['Ian']))
{'list_a': [], 'name': 'Ian', 'list_c': [], 'list_d': [], 'list_b': []}
>>> usr.set_lists()
select the user you intend on adding lists for: Ian
{'list_a': [], 'name': 'Ian', 'list_c': [], 'list_d': [], 'list_b': []}
how many lists would you like to create?(up to 4): 1
what would you like the list to be named?
thing
you have created 1 list, with the name:thing

我不认为您可以在创建类后更改属性的名称。我标记为see below的行只是将列表list_a更改为字符串。即使你可以,我也建议不要让用户决定他们的名字。您最终会得到同一个类的几个实例,这些实例都可能具有不同的属性。

如果您愿意,可以为该类创建一个名为lists的字典,并让用户将该列表添加到该字典中,并选择名称作为密钥。