我相信可读性和KISS原则是编程中最重要的事情.这就是为什么我使用Python :)
这是确切的情况,我经常遇到:
说,我有一个漂亮而干净的脚本,它是数据库处理的包装器:
import database_schema as schema
loader = schema.Loader("sqlite:///var/database.db")
session = loader.session
def addUser(name, full_name, password):
user = schema.User(name, full_name, password)
session.add(user)
session.commit()
def listUsers():
all_users = session.query(schema.User).all()
return all_users
Run Code Online (Sandbox Code Playgroud)
使用方式如下:
import database
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
Run Code Online (Sandbox Code Playgroud)
在某些时候,我想重写该模块,以便它可以在不同的路径上使用数据库(例如,用于单元测试).
那么,我的选择是什么?
最直观的是添加database_path == ""变量,然后......什么?使用setPath(new_path)函数设置它,然后将exception(if database_path == "": raise SomeException)添加到每个函数中,这只是丑陋的,任何人都不应该这样做.
全功能类,设置self._database_path初始化时间.
然后以这种方式使用:
from database import Database
database = Database("sqlite:///var/database.db")
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
Run Code Online (Sandbox Code Playgroud)
这已经是比第一个例子更多的代码行,并且增加了命名问题:Database在模块中调用一个类database是愚蠢的,不是吗?
很抱歉长时间阅读,这里是我的最后一个问题:
__init__在Python中没有模块函数这样的东西?对不起我的英语.
编辑:
所以,为了清楚说明,这个代码在我富有想象力的Python世界中会是什么样子:
import database_schema as schema
def __init__(database_path):
loader = schema.Loader(database_path)
global session
session = loader.session
def addUser(name, full_name, password):
user = schema.User(name, full_name, password)
session.add(user)
session.commit()
def listUsers():
all_users = session.query(schema.User).all()
return all_users
Run Code Online (Sandbox Code Playgroud)
像这样使用:
import database("sqlite:///var/database.db")
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
Run Code Online (Sandbox Code Playgroud)
模块是一个 Python 对象,具有可以绑定和引用的任意命名的属性。名为 mod 的模块的 Python 代码通常驻留在名为 mod.py 的文件中。当您尝试导入它时,会创建一个新的命名空间,其中包含该模块的所有属性。
尽管如此,它与类和该类的对象实例的创建不同。这些是不同的抽象,应该这样使用。
而不是测试
if database_path == "":
....
Run Code Online (Sandbox Code Playgroud)
做Python式的方式
if database_path:
....
Run Code Online (Sandbox Code Playgroud)
您可以使用断言,而不是引发异常
assert database_path != "", 'database path empty'
Run Code Online (Sandbox Code Playgroud)
模块不像类的对象实例那样存在。每次导入模块时,导入模块都会创建一个具有相同属性集的命名空间。在这种情况下,init可能没有多大意义。
您提供的第二种形式的代码没有任何问题。如果您不想这样做,上面的一些习语可能会减轻您的痛苦:)