所以我试图在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
这里我必须将一些东西作为第二个输入放入初始化,否则我会收到错误。像这样浪费。
答案 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)