如何在 Python 中的抽象 class 实现中使用 self?
How to use self in an abstract class implementation in Python?
我正在做一个项目,在 Python 中使用抽象 classes(特别是 abc 模块)。
我有几个这个抽象的实现 class,它们有自己的构造函数,需要使用 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
class - 但运气不好。
所以,差不多,我怎样才能在抽象方法的某些实现中使用 self
关键字(又名访问属性),它在抽象 class 方法中调用48=]本身。
此外,附带说明一下,如何从 BaseClass 的所有实现中访问 self.sublinks
,同时在每个实现实例中具有不同的值?
这里有一些错误。一个是 @classmethod
装饰器只应在需要在 class.
上调用时使用
示例:
class ImplementationOne:
@classmethod
def display(cls):
print(f'The class name is {cls.__name__}.')
ImplementationOne.display()
名字self
没有什么特别的。这只是每个人用来指代实例的东西。在 python 中,实例被隐式传递给 class 的第一个参数,除非你有一个 @classmethod
装饰器。在这种情况下,class 将作为第一个参数传递。
这就是您获得 TypeError
的原因。由于您在实例 test_one.display()
上调用该方法,因此您实际上是将其作为实例方法调用。由于您需要从其中访问实例方法 get_contents
,这就是您想要的。作为 classmethod
,您将无权访问 get_contents
。
这意味着您需要 ABC 和 ImplementationOne
才能将这些方法实现为实例方法。
因为它现在是 ABC 上的实例方法,所以它也应该是 ImplementationTwo
中的实例方法。
您的另一个问题是如何将 self.sublinks
作为两个子 class 中的属性。
由于您正在覆盖 ImplementationOne
中的 __init__
,因此您还需要调用父 class 的 __init__
。您可以通过使用 super()
调用 Super 或 Base class 的方法来做到这一点。
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)
我正在做一个项目,在 Python 中使用抽象 classes(特别是 abc 模块)。
我有几个这个抽象的实现 class,它们有自己的构造函数,需要使用 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
class - 但运气不好。
所以,差不多,我怎样才能在抽象方法的某些实现中使用 self
关键字(又名访问属性),它在抽象 class 方法中调用48=]本身。
此外,附带说明一下,如何从 BaseClass 的所有实现中访问 self.sublinks
,同时在每个实现实例中具有不同的值?
这里有一些错误。一个是 @classmethod
装饰器只应在需要在 class.
示例:
class ImplementationOne:
@classmethod
def display(cls):
print(f'The class name is {cls.__name__}.')
ImplementationOne.display()
名字self
没有什么特别的。这只是每个人用来指代实例的东西。在 python 中,实例被隐式传递给 class 的第一个参数,除非你有一个 @classmethod
装饰器。在这种情况下,class 将作为第一个参数传递。
这就是您获得 TypeError
的原因。由于您在实例 test_one.display()
上调用该方法,因此您实际上是将其作为实例方法调用。由于您需要从其中访问实例方法 get_contents
,这就是您想要的。作为 classmethod
,您将无权访问 get_contents
。
这意味着您需要 ABC 和 ImplementationOne
才能将这些方法实现为实例方法。
因为它现在是 ABC 上的实例方法,所以它也应该是 ImplementationTwo
中的实例方法。
您的另一个问题是如何将 self.sublinks
作为两个子 class 中的属性。
由于您正在覆盖 ImplementationOne
中的 __init__
,因此您还需要调用父 class 的 __init__
。您可以通过使用 super()
调用 Super 或 Base class 的方法来做到这一点。
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)