ในภารกิจที่ไม่มีที่สิ้นสุดของฉันในเรื่องง่าย ๆ ที่ซับซ้อนเกินไปฉันกำลังค้นคว้าวิธี 'Pythonic' ส่วนใหญ่เพื่อจัดหาตัวแปรการกำหนดค่าส่วนกลางภายใน ' config.py ' ทั่วไปที่พบในแพ็คเกจไข่ Python
วิธีดั้งเดิม (aah, good ol ' #define !) มีดังนี้:
MYSQL_PORT = 3306
MYSQL_DATABASE = 'mydb'
MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']
ดังนั้นการนำเข้าตัวแปรส่วนกลางด้วยวิธีใดวิธีหนึ่งต่อไปนี้:
from config import *
dbname = MYSQL_DATABASE
for table in MYSQL_DATABASE_TABLES:
print table
หรือ:
import config
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT, int))
มันสมเหตุสมผล แต่บางครั้งอาจจะยุ่งเล็กน้อยโดยเฉพาะอย่างยิ่งเมื่อคุณพยายามจำชื่อของตัวแปรบางตัว นอกจากนี้การจัดเตรียมออบเจ็กต์ "การกำหนดค่า"โดยมีตัวแปรเป็นคุณลักษณะอาจมีความยืดหยุ่น ดังนั้นการเป็นผู้นำจากไฟล์bpython config.py ฉันจึงมาพร้อมกับ:
class Struct(object):
def __init__(self, *args):
self.__header__ = str(args[0]) if args else None
def __repr__(self):
if self.__header__ is None:
return super(Struct, self).__repr__()
return self.__header__
def next(self):
""" Fake iteration functionality.
"""
raise StopIteration
def __iter__(self):
""" Fake iteration functionality.
We skip magic attribues and Structs, and return the rest.
"""
ks = self.__dict__.keys()
for k in ks:
if not k.startswith('__') and not isinstance(k, Struct):
yield getattr(self, k)
def __len__(self):
""" Don't count magic attributes or Structs.
"""
ks = self.__dict__.keys()
return len([k for k in ks if not k.startswith('__')\
and not isinstance(k, Struct)])
และ 'config.py' ที่นำเข้าคลาสและอ่านดังนี้:
from _config import Struct as Section
mysql = Section("MySQL specific configuration")
mysql.user = 'root'
mysql.pass = 'secret'
mysql.host = 'localhost'
mysql.port = 3306
mysql.database = 'mydb'
mysql.tables = Section("Tables for 'mydb'")
mysql.tables.users = 'tb_users'
mysql.tables.groups = 'tb_groups'
และใช้ในลักษณะนี้:
from sqlalchemy import MetaData, Table
import config as CONFIG
assert(isinstance(CONFIG.mysql.port, int))
mdata = MetaData(
"mysql://%s:%s@%s:%d/%s" % (
CONFIG.mysql.user,
CONFIG.mysql.pass,
CONFIG.mysql.host,
CONFIG.mysql.port,
CONFIG.mysql.database,
)
)
tables = []
for name in CONFIG.mysql.tables:
tables.append(Table(name, mdata, autoload=True))
ซึ่งดูเหมือนจะเป็นวิธีการจัดเก็บและดึงข้อมูลตัวแปรส่วนกลางภายในแพ็คเกจที่อ่านง่ายและยืดหยุ่นกว่า
ความคิดที่เลวร้ายที่สุดที่เคย? แนวทางปฏิบัติที่ดีที่สุดในการรับมือกับสถานการณ์เหล่านี้คืออะไร? อะไรคือสิ่งที่คุณวิธีการจัดเก็บและเรียกชื่อระดับโลกและตัวแปรภายในแพคเกจของคุณหรือไม่