【问题标题】:Need Clarification on Using OOP and DRY Method in Python需要澄清在 Python 中使用 OOP 和 DRY 方法
【发布时间】:2015-06-10 17:34:12
【问题描述】:

我试图通过应用 OOP 和 DRY 方法来保持我的代码干净;但是,我发现自己陷入了以下问题。

1) 由于 checkremotebackup 方法依赖于 sshlogin 方法,有没有另一种写法,以便我的对象是完全初始化了吗?

2) 如果没有更好的方法,我在哪里编写 PhoneBook 类的过程以按以下方式执行(1 - checklocal,2 - sshlogin,3 - checkremote,4 - 备份)?主要吗?

class PhoneBook:

    def __init__ (self, name, phone_number, birthdate, location):
        self.name = name
        self.phone_number = phone_number
        self.birthdate = birthdate
        self.location = location
        self.ssh = None

    def checklocal (self):
        # Check local phonebook for existing names
        pass


    def sshlogin (self):
        # SSH into remote server


    def checkremote (self):
        # Check remote phonebook for existing names
        pass


    def backup (self):
        # Backup remote phonebook

【问题讨论】:

  • 为什么会有AddDelete 类?添加或删除是一种电话簿吗?
  • 同意@kindall。它们可能应该是电话簿类的方法,或独立的通用函数。
  • 谢谢。我会做出改变。
  • @kindall 我已经编辑了问题以摆脱AddDelete 的东西。首先它确实与问题无关。

标签: python oop dry


【解决方案1】:

在这种情况下,您可能希望使用上下文管理器和 with 关键字。

由于使用Phonebook 对象需要事先进行“设置”阶段,因此您需要确保每次使用它时都能正确处理。所以你可以写出这样的代码:

with Phonebook(name, phone_number, birthdate, location) as phbk: 
    #do stuff with the phonebook
    phbk.add(name, phone_number, birthdate, location)

您的所有设置阶段步骤 - 检查本地副本、连接(和断开) ssh 会话、检查远程副本、备份等 - 将在“幕后”发生,作为设置/拆除的一部分上下文管理器(换句话说,with 语句负责所有这些)。这类似于您应该如何使用open()

with open('myfile') as file:
    lines = file.readlines()

干净地打开和关闭文件发生在“幕后”,自动。这可能是您希望在电话簿中发生的事情。

要使上下文管理器正常工作,您可以使用 python __enter____exit__ 魔术方法。可能看起来像这样:

class PhoneBook:

    def __init__ (self, name, phone_number, birthdate, location):
        self.name = name
        self.phone_number = phone_number
        self.birthdate = birthdate
        self.location = location
        self.ssh = None

    def sshlogin(self):
        # SSH into remote server

    def sshlogout(self):
        # SSH out of remote server

    def checklocal(self):
        # Check local phonebook for existing names
        pass        

    def checkremote (self):
        # Check remote phonebook for existing names
        pass            

    def backup (self):
        # Backup remote phonebook

    def __enter__(self):
        self.checklocal()
        self.sshlogin()
        self.checkremote()
        self.backup()
        return self

    def __exit__(self, cls, value, traceback):
        self.sshlogout()
        return False

至于你的Add(和Delete)类,它真的不应该是一个类。它可能应该是:

  • Phonebook 类的方法,如下所示:

    class Phonebook:
        def __init__(self):
            self.ssh = None
        def add(self, name, phone_number, birthdate, location):
            self.name = name
            self.phone_number = phone_number
            self.birthdate = birthdate
            self.location = location
    

  • 一个通用函数,像这样:

    def Add(phbk, name, phone_number, birthdate, location):
        # add to remote phonebook
    

还有一点:你的 Phonebook 类的命名不是很好。基于__init__ 方法,它更像是一个电话簿条目。您可能需要考虑单独实现您的电话簿(作为上下文管理器,如上所述)作为某种容器来保存您的条目(包括 adddelete 方法),并专注于 Phonebook 类你有(重命名为Entry 或其他东西)更多的是可以添加到新的Phonebook 对象的电话簿Entry 对象,在这种情况下,添加方法可能更像这样:

    def add(self, entry):
        try:
            self.entries.append(entry)
        except AttributeError:
            self.entries = [entry] 

另外一件事:我注意到您使用制表符来定义您的类、函数等等。这是against the recommended practice - 请改用 4 个空格。

进一步的建议:对于像我建议的 Entry 类这样简单的东西,您可能只想使用 collections.namedtuple,如下所示:

from collections import namedtuple as nt
Entry = nt('Entry', 'name phone_number birthdate location')

现在你可以做这样的事情了:

e = Entry('rick', '8675309', '1/1/2001', '125 Sesame St`)
print(e.name)

【讨论】:

  • 感谢 Rick 花时间布置细节。我会试试看。
  • @dreamzboy 没问题,但最好的感谢方式是投票并接受答案(绿色复选标记)。
  • @dreamzboy 更多关于 with 声明可以找到here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
相关资源
最近更新 更多