如何解决如何在 Python 的抽象类实现中使用 self?
我正在使用 Python 中的抽象类(特别是 abc 模块)开发一个项目。
我有一些这个抽象类的实现,它们有自己的构造函数,需要使用 self
。
这是我的代码的样子,但经过简化:
from abc import ABC,abstractmethod
class BaseClass(ABC):
def __init__(self):
self.sublinks = [] # not meant to be passed in,that's why it isn't an argument in __init__
@classmethod
def display(cls):
print(cls.get_contents())
@abstractmethod
def get_contents():
pass
class ImplementationOne(Base):
def __init__(self,url):
self.url = url
def get_contents(self):
return "The url was: " + url
class ImplementationTwo(Base):
def get_contents():
return "This does not need a url"
test_one = ImplementationOne("https://google.com")
test_two = ImplementationTwo()
test_one.display()
然而,当我运行它时,我收到错误 TypeError: get_contents() missing 1 required positional argument: 'self'
。
我认为这是因为ImplementationOne中的get_contents()
需要self
,但在抽象方法中没有指定。
所以,如果我改变了:
@abstractmethod
def get_contents():
pass
到
@abstractmethod
def get_contents(self):
pass
但我得到了同样的错误。
我尝试了很多组合,包括将 self
作为参数放在每次出现或 get_contents
中,以及在抽象类中将 cls
传递给 get_contents
- 但是没有运气。
所以,差不多,我如何仅在抽象方法的某些实现中使用 self
关键字(又名访问属性),该方法在抽象类本身的类方法中调用。
另外,附带说明一下,如何从 BaseClass 的所有实现中访问 self.sublinks
,同时在每个实现实例中具有不同的值?
解决方法
这里有一些错误。一个是 @classmethod
装饰器应该只在您需要在类上调用它时使用。
示例:
class ImplementationOne:
@classmethod
def display(cls):
print(f'The class name is {cls.__name__}.')
ImplementationOne.display()
self
这个名字没有什么特别之处。这只是每个人用来引用实例的东西。在 python 中,除非您有 @classmethod
装饰器,否则实例被隐式传递给类的第一个参数。在这种情况下,类将作为第一个参数传递。
这就是您获得 TypeError
的原因。由于您在实例 test_one.display()
上调用方法,因此您实际上是将其作为实例方法调用。由于您需要从其中访问实例方法 get_contents
,这正是您想要的。作为 classmethod
,您将无权访问 get_contents
。
这意味着您需要 ABC 和 ImplementationOne
才能将这些方法实现为实例方法。
既然它现在是 ABC 上的实例方法,它也应该是 ImplementationTwo
中的实例方法。
您的另一个问题是如何将 self.sublinks
作为两个子类中的属性。
由于您在 __init__
中覆盖 ImplementationOne
,因此您还需要调用父类的 __init__
。为此,您可以使用 super()
调用 Super 或 Base 类的方法。
class ImplementationOne(BaseClass):
def __init__(self,url):
self.url = url
super().__init__()
完整的工作代码:
from abc import ABC,abstractmethod
class BaseClass(ABC):
def __init__(self):
self.sublinks = []
def display(self):
print(self.get_contents())
@abstractmethod
def get_contents(self):
pass
class ImplementationOne(BaseClass):
def __init__(self,url):
self.url = url
super().__init__()
def get_contents(self):
return "The url was: " + self.url
class ImplementationTwo(BaseClass):
def get_contents(self):
return "This does not need a url"
test_one = ImplementationOne("https://google.com")
test_two = ImplementationTwo()
test_one.display()
test_two.display()
print(test_one.sublinks)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。