应用@staticmethod,python3

时间:2014-01-04 05:14:13

标签: python static-methods

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


    @staticmethod
    def create_new_user(x):
        x=userinput("x","","","","")
        users.append(x)

我打算创建一个生成新用户的函数,只返回一个名称给用户而没有列表,因此在名称槽中有x。

我的问题:这是@staticmethod的正确用法还是我错过了它的全部内容?

根据我的理解,它允许用户在这种情况下使用userinput.create_new_user('tim')而不必预先定义类,tim = userinput(“foo”,“”,“”,“”,“ “);它在现场创造它。

我试图将函数create_new_users转换为:

@staticmethod
def create_new_user():
    print("how many users do you want to create")
    x=int(input())
    y=0
    while y < x:
        print("assign the users names")
        name = input("")
        if name == "" or "None,none":
            raise SyntaxError("name cannot be None or empty")
            break

        name=userinput("","","","","")      
        userinput.users.append(name)
        y+=1

2 个答案:

答案 0 :(得分:3)

在静态方法中你不能使用类变量,你的代码应该

NameError: global name 'users' is not defined

修改

使用userinput.users.append

答案 1 :(得分:1)

使用@classmethod将是最简单的选择。

class UserInput: # capitals! Look at PEP 8.
    users = [] # rearranged to the top for better readability

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

    @classmethod
    def create_new_user(cls): # no need for x if you overwrite it immediately
        x = cls("x", "", "", "", "")
        cls.users.append(x) # easier access to this static attribute
        return x # for the caller having access to it as well.

如果我们将UserInput子类化,因为它使用了新类,那么它也可以。

但请注意,x = cls("x", "", "", "", "")不会非常有用;做得更好

    @classmethod
    def create_new_user(cls, *a, **k): # no need for x if you overwrite it immediately
        x = cls(*a, **k) # pass the arguments given by the caller to __init__.
        cls.users.append(x) # easier access to this static attribute
        return x # for the caller having access to it as well.

我现在可以这样使用:

a = UserInput("foo", "whatever", "is", "needed", "here")

或者,如果我选择,

a = UserInput.create_new_user("foo", "whatever", "is", "needed", "here")

另外将新用户附加到列表中。

如果您希望能够缩短参数列表,也可以这样做:

    def __init__(self, name, lista=None, listb=None, listc=None, listd=None):
        self.name = name
        self.lista = lista if lista is not None else []
        self.listb = listb if listb is not None else []
        self.listc = listc if listc is not None else []
        self.listd = listd if listd is not None else []

如果他们真的是名单。如果它们是字符串,则另一个名称是合适的,并且由于字符串是不可变的,您可以简单地执行

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

并用

调用这些东西
a = UserInput.create_new_user("foo", listc=...) # all others are left empty
b = UserInput("bar") # all are left empty
c = UserInput.create_new_user("ham", lista=..., listd=...) # all others are left empty

既然你提出了不同的任务,我也会尝试解决这个问题:

@classmethod
def create_new_users(cls): # several users!
    print("how many users do you want to create")
    num = int(input())
    for _ in range(num): # simpler iteration
        print("enter the user's name")
        name = input("") # in 3.x, this is always a string, so it cannot be None...
        # if name == "" or "None,none": # That won't work as you think.
        if name == '' or name.lower() == 'none': # but why disallow the string 'None'?
            # raise SyntaxError("name cannot be None or empty")
            raise RuntimeError("name cannot be None or empty") # or ValueError or alike
            # break not needed. raise jumps out without it as well.
        user = cls(name, "", "", "", "") # name is an input, not an output.
        cls.users.append(name)

但是我想知道这个类是否真的是存储新用户的正确位置,而且只有那些使用此功能创建的用户。也许最好直接在users中提供__init__列表,并让此功能处于更高级别。


在这里使用@classmethod的好处是你总是在相关的基础上工作。

想象一下,如上所述,您拥有UserInput方法__init__()。然后你可以将它子类化并执行

UserInput.create_new_users()使用@classmethod将是最简单的选择。

class UserInputStoring(UserInput):
    users = [] # this is only here, not at the parent.
    def __init__(self, *a, **k):
        super(UserInputStoring, self).__init__(*a, **k) # pass everything up as it was used
        self.users.append(self)

现在,您可以在基类中使用create_new_users()并成为@classmethod,然后根据您的调用方式选择正确__init__来调用。