การนำเข้ารายการค่าคงที่แบบยาวไปยังไฟล์ Python


92

ใน Python มีอะนาล็อกของCคำสั่งพรีโปรเซสเซอร์เช่นหรือไม่:

#define MY_CONSTANT 50

นอกจากนี้ฉันมีรายการค่าคงที่จำนวนมากที่ฉันต้องการนำเข้าในหลายชั้นเรียน มีอะนาล็อกของการประกาศค่าคงที่เป็นลำดับคำสั่งที่ยาวเหมือนข้างบนใน.pyไฟล์และนำเข้า.pyไฟล์อื่นหรือไม่?

แก้ไข.

ไฟล์Constants.pyอ่าน:

#!/usr/bin/env python
# encoding: utf-8
"""
Constants.py
"""

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

และmyExample.pyอ่าน:

#!/usr/bin/env python
# encoding: utf-8
"""
myExample.py
"""

import sys
import os

import Constants

class myExample:
    def __init__(self):
        self.someValueOne = Constants.MY_CONSTANT_ONE + 1
        self.someValueTwo = Constants.MY_CONSTANT_TWO + 1

if __name__ == '__main__':
    x = MyClass()

แก้ไข.

จากคอมไพเลอร์

NameError: ไม่ได้กำหนด "ชื่อสากล" MY_CONSTANT_ONE "

function initใน myExample ที่บรรทัด 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 copy output โปรแกรมออกจากโค้ด # 1 หลังจาก 0.06 วินาที


2
ไม่ไม่มีตัวประมวลผลล่วงหน้า และไม่คุณจะไม่ต้องพยายามโค้ด C ใน Python หรือแม้แต่พยายามค้นหาแนวขนาน

นั่นไม่ใช่การย้อนกลับแบบเต็ม คุณทำงานอย่างไร? python myExample.pyควรให้การย้อนกลับเกี่ยวกับข้อผิดพลาดที่มีชื่อไฟล์และ<module>เป็นระดับบนสุด นอกจากMY_CONSTANT_ONE นี้ยังไม่ได้อ้างอิงเป็นชื่อสากล - แปลกจริงๆ ตรวจสอบสามครั้งว่าไฟล์เหล่านี้เป็นไฟล์ที่คุณกำลังใช้งานอยู่จริง (และอาจแปลงเป็น ASCII และถอด# encoding: utf8บิตออก)

@ ทุกคน: ขอบคุณตอนนี้ฉันดูเหมือนจะสบายดี - ยังไม่แน่ใจว่าทำไม แต่ไม่เป็นไร :)
SK9

คำตอบ:


138

Python ไม่ได้ประมวลผลล่วงหน้า คุณสามารถสร้างไฟล์myconstants.py:

MY_CONSTANT = 50

และการนำเข้าจะใช้งานได้:

import myconstants
print myconstants.MY_CONSTANT * 2

@ SK9: แสดงรหัสที่คุณกำลังใช้งานอยู่ (ทั้งการกำหนดและการใช้โมดูล)

@ โทมัส: ดูด้านบน ฉันพลาดบางอย่างที่บ้าคลั่งไปแล้วเมื่อฉันเรียนรู้พื้นฐาน
SK9

@ SK9: ไม่มีข้อผิดพลาดดังกล่าวในรหัสที่คุณโพสต์ ฉันตรวจสอบหลายครั้งและเรียกใช้ด้วยตัวเองมันใช้งานได้ดี มันไม่สามารถนำไปสู่ข้อผิดพลาดนี้ได้ (ไม่มีการอ้างอิงถึงชื่อMAX_FIVE_FLUSH_KEY_INT) โพสต์การย้อนกลับ

@ โทมัส: ขอบคุณสำหรับการทดสอบนี้ ฉันจะลองอีกครั้ง (ข้อมูลอ้างอิงที่พาดพิงเป็นการพิมพ์ผิด) คุณลองใช้ไฟล์ตามตัวอักษรแล้วหรือยัง? (ฉันคัดลอกและวางเนื้อหาทั้งหมดด้านบน)
SK9

@ SK9: ฉันไม่ใช่โทมัส;) และใช่ฉันคัดลอกและวางทุกอย่างฉันยังทิ้งชื่อไฟล์ไว้เหมือนเดิม อีกครั้งการย้อนกลับจะช่วยเราในการดีบัก

18

Python ไม่มีตัวประมวลผลล่วงหน้าและไม่มีค่าคงที่ในแง่ที่ไม่สามารถเปลี่ยนแปลงได้ - คุณสามารถเปลี่ยนแปลงได้ตลอดเวลา (เกือบคุณสามารถเลียนแบบคุณสมบัติของวัตถุคงที่ได้ แต่การทำเช่นนี้เพื่อประโยชน์ของค่าคงที่แทบจะไม่เกิดขึ้น ทำแล้วไม่คิดว่ามีประโยชน์) ทุกอย่าง เมื่อกำหนดค่าคงที่เราจะกำหนดชื่อที่เป็นตัวพิมพ์ใหญ่พร้อมขีดล่างและเรียกมันว่า a day - "เราทุกคนยินยอมให้ผู้ใหญ่อยู่ที่นี่" ไม่มีผู้ชายที่มีสติสามารถเปลี่ยนค่าคงที่ได้ เว้นแต่ว่าเขาจะมีเหตุผลที่ดีมากและรู้แน่ชัดว่าเขากำลังทำอะไรอยู่ซึ่งในกรณีนี้คุณทำไม่ได้ (และไม่ควร) หยุดเขาด้วยวิธีใด

แต่แน่นอนคุณสามารถกำหนดชื่อระดับโมดูลด้วยค่าและใช้ในโมดูลอื่นได้ สิ่งนี้ไม่ได้เจาะจงเฉพาะค่าคงที่หรือสิ่งใด ๆ โปรดอ่านในระบบโมดูล

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

11

และแน่นอนคุณสามารถทำได้:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT


3
โดยทั่วไปไม่สนับสนุนการนำเข้า * แต่ค่าคงที่ของรายการรูปแบบ C ที่ใช้กันอย่างแพร่หลายในโค้ดเบสเป็นหนึ่งในสถานที่ที่ไม่น่าใช้ การตั้งชื่อเป็น ALL_CAPS หรือด้วยรูปแบบคำนำหน้าบางอย่างที่ลดความเป็นไปได้ในการชนกับสัญลักษณ์อื่น ๆ จะลบการคัดค้านหลักของสำนวนและหากเกิดการชนกันคุณสามารถถอยกลับไปใช้สไตล์การนำเข้าแบบเดิม + ชื่อที่ชัดเจนได้เสมอ .MY_CONSTNAT) ไม่เหมือนใน C.
Russell Borogove

ยัง a.MY_CONSTNAT ช้าลงเล็กน้อยนั่นเป็นเพราะล่ามมองหาในเนมสเปซเดียวสำหรับชื่อ 'a' จากนั้นในชื่อศัตรูตัวที่สอง 'MY_CONSTNAT'
tony

7

แน่นอนว่าคุณใส่ค่าคงที่ลงในโมดูลแยกกันได้ ตัวอย่างเช่น:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

print const.A, const.B, const.C

โปรดทราบว่าตามที่ประกาศข้างต้นA, BและCเป็นตัวแปรเช่นสามารถเปลี่ยนแปลงได้ในเวลาทำงาน


5

ลองดูสร้างค่าคงที่โดยใช้โมดูล "การตั้งค่า" ไหม และฉันสามารถป้องกันการแก้ไขวัตถุใน Python ได้หรือไม่

ลิงก์ที่มีประโยชน์อีกลิงก์หนึ่ง: http://code.activestate.com/recipes/65207-constants-in-python/บอกเราเกี่ยวกับตัวเลือกต่อไปนี้:

from copy import deepcopy

class const(object):

    def __setattr__(self, name, value):
        if self.__dict__.has_key(name):
            print 'NO WAY this is a const' # put here anything you want(throw exc and etc)
            return deepcopy(self.__dict__[name])
        self.__dict__[name] = value

    def __getattr__(self, name, value):
        if self.__dict__.has_key(name):
            return deepcopy(self.__dict__[name])

    def __delattr__(self, item):
        if self.__dict__.has_key(item):
            print 'NOOOOO' # throw exception if needed

CONST = const()
CONST.Constant1 = 111
CONST.Constant1 = 12
print a.Constant1 # 111
CONST.Constant2 = 'tst'
CONST.Constant2 = 'tst1'
print a.Constant2 # 'tst'

ดังนั้นคุณสามารถสร้างคลาสแบบนี้แล้วนำเข้าจากโมดูล contants.py ของคุณ ซึ่งจะช่วยให้คุณมั่นใจได้ว่าจะไม่มีการเปลี่ยนแปลงลบออก


ขอบคุณสำหรับสิ่งนี้. ก่อนที่จะถามฉันจึงค้นหาและพบทั้งสองอย่างนี้ :)
SK9

@ SK9 โอ้ขอโทษที่ทำซ้ำแล้ว
Artsiom Rudzenka

4

อีกทางเลือกหนึ่งนอกเหนือจากการใช้วิธีการนำเข้าที่อธิบายไว้ในหลาย ๆ คำตอบให้ดูที่โมดูลconfigparser

คลาส ConfigParser ใช้ภาษาตัวแยกวิเคราะห์ไฟล์คอนฟิกูเรชันพื้นฐานซึ่งมีโครงสร้างคล้ายกับที่คุณพบในไฟล์ Microsoft Windows INI คุณสามารถใช้สิ่งนี้เพื่อเขียนโปรแกรม Python ซึ่งผู้ใช้ปลายทางสามารถปรับแต่งได้อย่างง่ายดาย


2

หากคุณต้องการค่าคงที่จริง ๆ ไม่ใช่แค่ตัวแปรที่ดูเหมือนค่าคงที่วิธีมาตรฐานในการทำคือใช้พจนานุกรมที่ไม่เปลี่ยนรูป น่าเสียดายที่ยังไม่ได้ติดตั้งในตัวคุณจึงต้องใช้สูตรของบุคคลที่สาม (เช่นสูตรนี้หรือสูตรนั้น )


2

สร้างไฟล์คงที่ด้วยชื่อใด ๆ เช่น my_constants.py ประกาศค่าคงที่เช่นนั้น

CONSTANT_NAME = "SOME VALUE"

สำหรับการเข้าถึงค่าคงที่ในไฟล์นำเข้ารหัสของคุณเช่นนั้น

import my_constants as constant

และเข้าถึงค่าคงที่เป็น -

constant.CONSTANT_NAME
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.