【问题标题】:Shall I override default fields using inheritance?我应该使用继承覆盖默认字段吗?
【发布时间】:2020-10-06 09:14:33
【问题描述】:

编辑:ChatterOne 的回答很好。我必须保持简单。没有任何奇怪/古怪的行为值得避免重复一个简单、明确和有用的变量。

我想要的(伪代码示例):摆脱“服务器”参数。

Config.default_values.server = Server.application
class ApplicationDbConfig(Enum):
    database_1 = Config(Database.db1)
    database_2 = Config(Database.db2)
    ...


Config.default_values.server = Server.warehouse
class WarehouseDatabaseConfig(Enum):
    database_1 = Config(Database.db1)
    database_2 = Config(Database.db2)
    ...

最好的解决方案是:

保持你的变量明确。无需隐藏它或在内部更改状态。 明确和清晰更好。所以我将放弃摆脱s 的目标并保持简单。

s = Server.application
class ApplicationDatabaseConfig(Enum):
    database_1 = Config(Database.db1, s)
    database_2 = Config(Database.db2, s)
    ...


s = Server.warehouse
class WarehouseDatabaseConfig(Enum):
    database_1 = Config(Database.db1, s)
    database_2 = Config(Database.db2, s)
    ...

最初的问题是: 使用继承来覆盖默认参数是否值得?或者你有更好的方法吗?

这是我用来执行此操作的原始代码,使用继承。它占用了太多空间,并为观看者增加了很多噪音。

@dataclass
class Config:
    database: Database
    server: Server
    driver: Driver = Driver.sql_serv_native_client_11
    is_trusted: bool = True
    additional_params: str = None


@dataclass
class ApplicationConfig(Config): server: Server = Server.application
    
@dataclass
class WarehouseConfig(Config): server: Server = Server.warehouse

...

class ApplicationDatabasesConfig(Enum):
    database_1 = ApplicationConfig(Database.db1)
    database_2 = ApplicationConfig(Database.db2)
    ...


class WarehouseDatabasesConfig(Enum):
    database_3 = WarehouseConfig(Database.db3)
    database_4 = WarehouseConfig(Database.db4)
    ...

【问题讨论】:

  • 我不确定,也许我在这里遗漏了什么,但是为什么不在创建实例时传递服务器名称或配置并在类的__init__ 中读取它?
  • 因为我想去掉那个参数。由于我在ServerX中有很多数据库,所以我不得不多次编写参数server=Server.serverX。这似乎是多余的。
  • 我还是不明白你的意思,抱歉。您只需编写一次 server = config.server ,即在基类的 init 方法中。然后,当您使用 config = Config(server1)config = Config(server2) 之类的内容实例化该类时。
  • 我做了一个更好的例子来说明我要归档的内容。我希望它能澄清我要做的事情。顺便说一句,谢谢你的帮助。我会尽量说清楚!
  • 您的最新示例正是我的意思,我认为这就是您应该如何实现它。也许我会尝试写一个答案,看看是否是你的意思。

标签: python python-3.x class enums


【解决方案1】:

假设你想要用不同的参数实例化同一个类,除了一些可能有也可能没有默认值的类,我会做这样的事情(未经测试,只是快速输入),还假设你有一个默认的驱动程序:

class Config:
    def __init__(self, database, server=Server.serverX, driver=Driver.default, is_trusted=True, additional_params=None):
        self.database = database
        self.driver = driver
        self.server = server
        self.is_trusted = is_trusted
        self.additional_params = additional_params

然后你可以像这样使用它:

database_1 = Config(Database.db1)
database_2 = Config(Database.db2)
database_3 = Config(Database.db3)
database_4 = Config(Database.db4, Server.serverY)

但这对我来说看起来很简单,所以也许我错过了一些东西。

顺便说一句,您也可以将其与命名参数一起使用,例如

database_4 = Config(database=Database.db4, server=Server.serverY)

如果您想更详细/更明确(同样,未经测试,可能存在拼写错误)。

【讨论】:

  • 我会清理我的问题并接受您的回答。经过深思熟虑,保持清晰和简单确实是最好的方法。有时你过于关注 DRY'ing 你的代码..
  • 您在我的代码中看不到 init 的原因是因为我使用了@dataclass。你应该查一下,它很整洁。
  • @FlorianFasmeyer 我知道数据类,但这就是重点(你已经注意到我没有将它包含在我的代码中)。如果有什么东西让你的代码变得更复杂、更不可读,那么你需要一个非常强大的案例来继续使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多