如何在类启动中删除不需要的参数?

时间:2017-07-20 19:24:02

标签: python python-3.x oop

所以我试图在Python中掌握OOP。我遇到的问题是在初始化子类的对象时,我仍然需要输入我不需要的信息。

具体来说,我正在努力创建一个Person对象而不指定can_speak。所以我可以这样做:

John = person("John Anderson")

无需在初始化时输入can_speak

class Animal(object):
    def __init__(self, name, can_speak):
        self.name = name
        self.can_speak = False

class Dog(Animal):
    pass

class Person(Animal):
    def __init__(self, name, can_speak):
        self.name = name
        self.can_speak = True

Bob = Person("Bob the Builder", 3.141)
print(Bob.name)
print(Bob.can_speak)
# Bob the Builder
# True

Sam = Dog("Sam the Mutt", 0.00059)
print(Sam.name)
print(Sam.can_speak)
# Sam the Mutt
# False

这里我必须将一些东西作为第二个输入放入初始化,否则我会收到错误。像这样浪费。

3 个答案:

答案 0 :(得分:5)

不必为对象拥有的每个属性添加参数。您只需在Animal级别填写,然后在Person级别覆盖,例如:

class Animal(object):
    def __init__(self, name):  # look ma, no can_speak parameter
        self.name = name
        self.can_speak = False

class Dog(Animal):
    pass

class Person(Animal):
    def __init__(self, name):   # look ma, no can_speak parameter
        super().__init__(name)  # perform a super call
        self.can_speak = True   # override the can_speak

如果应该如何构造这样的对象,你只需要添加一个参数取决于输入

此外请注意,您无需添加此类属性附加到对象。您可以将属性附加到类,或定义方法。例如:

class Animal(object):

    can_speak = False

    def __init__(self, name):  # look ma, no can_speak parameter
        self.name = name

class Dog(Animal):
    pass

class Person(Animal):

    can_speak = True

现在我们存储Animal是否可以在类中说出。这将导致更少的内存使用,而我们仍然可以得到动物是否能说话:

>>> a = Animal('foo')
>>> a.can_speak
False
>>> p = Person('bar')
>>> p.can_speak
True

然而,我们仍然可以为一只狗添加一个属性can_speak(例如,在比利时,有一个电视节目关于一只名为 Samson 虚构的说话的狗>):

>>> samson = Dog('Samson')
>>> samson.can_speak = True
>>> samson.can_speak
True
>>> foo = Dog('other dog')
>>> foo.can_speak
False

答案 1 :(得分:3)

假设Animal是具有属性can_speak的Base类,则默认为传递给构造函数的变量,该变量再次默认为False。

在子类Dog中调用它的基本构造函数,因此无法说话。但是Person正在调用基础构造函数,True的值为can_speak

所以你可以创造一个不能说话的人的对象和可以说话的动物(如鹦鹉)。通过遵循以下方法,can_speak变量在所有类中保持不变,而不是在子类中重复,并且可以通过传递参数而不是在子类中手动更改来更改。

尝试以下

class Animal(object):
    def __init__(self, name, can_speak=False):
        self.name = name
        self.can_speak = can_speak

class Dog(Animal):
    pass

class Person(Animal):
    def __init__(self, name, can_speak=True):
        super(Person, self).__init__(name, can_speak)

Bob = Person("Bob the Builder")
print(Bob.name)
print(Bob.can_speak)
# Bob the Builder
# True

Sam = Dog("Sam the Mutt")
print(Sam.name)
print(Sam.can_speak)
# Sam the Mutt
# False

答案 2 :(得分:2)

首先,您应该始终使用内置函数 native.new_http_archive( name = "eigen_archive", urls = [ "http://mirror.bazel.build/bitbucket.org/eigen/eigen/get/d781c1de9834.tar.gz", "https://bitbucket.org/eigen/eigen/get/d781c1de9834.tar.gz", ], sha256 = "a34b208da6ec18fa8da963369e166e4a368612c14d956dd2f9d7072904675d9b", strip_prefix = "eigen-eigen-d781c1de9834", build_file = str(Label("//third_party:eigen.BUILD")), ) 并调用父super(),除非您确定不想这样做。父级可以初始化超过这两个属性,您必须将其复制到容易出错的子级__init__()中。

现在,您可以通过多种方式完成任务:

  • 使用默认值

    __init__()

    在这种情况下,您仍然可以创建class Person(Animal): def __init__(self, name, can_speak = True): super().__init__(name, can_speak) 的实例,并设置他不会说话(他可以说不出话)。

  • 如果您不想支持无言以对的人,那么您可以这样做:

    Person
  • 但是参数可能会产生误导,所以你可以省略它(从这一点来看,父和子有不同的构造函数参数,这通常不是问题):

    class Person(Animal):
        def __init__(self, name, can_speak = True):
            super().__init__(name, True)