Mengimpor daftar panjang konstanta ke file Python

90

Di Python, apakah ada analogi dari Cpernyataan preprocessor seperti ?:

#define MY_CONSTANT 50

Juga, saya memiliki daftar besar konstanta yang ingin saya impor ke beberapa kelas. Apakah ada analog untuk mendeklarasikan konstanta sebagai rangkaian pernyataan yang panjang seperti di atas dalam sebuah .pyfile dan mengimpornya ke .pyfile lain ?

Sunting.

File tersebut Constants.pyberbunyi:

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

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

Dan myExample.pyberbunyi:

#!/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()

Sunting.

Dari penyusun,

NameError: "nama global 'MY_CONSTANT_ONE' tidak ditentukan"

function init di myExample di baris 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 salinan output Program keluar dengan kode # 1 setelah 0,06 detik.

SK9
sumber
2
Tidak, tidak ada praprosesor. Dan tidak, Anda tidak akan terlalu jauh mencoba kode C dengan Python, atau bahkan mencoba menemukan persamaan.
Itu bukan traceback penuh. Bagaimana Anda menjalankannya? python myExample.pyharus memberikan traceback pada kesalahan yang menyertakan nama file dan <module>sebagai level teratas. Plus, MY_CONSTANT_ONE bukan referensi sebagai nama global - benar-benar aneh. Periksa tiga kali apakah itu benar-benar file yang Anda jalankan (dan mungkin mengubahnya menjadi ASCII dan hapus # encoding: utf8bitnya).
@ Semua: Terima kasih, sepertinya saya baik-baik saja sekarang - belum yakin mengapa, tapi sudahlah :).
SK9

Jawaban:

132

Python tidak diproses sebelumnya. Anda bisa membuat file myconstants.py:

MY_CONSTANT = 50

Dan mengimpornya hanya akan berfungsi:

import myconstants
print myconstants.MY_CONSTANT * 2
Thomas K
sumber
@ SK9: Baiklah, tunjukkan kode persis yang Anda jalankan (baik mendefinisikan dan menggunakan modul).
@ Thomas: Lihat di atas. Saya pasti melewatkan sesuatu yang aneh di beberapa tempat saat saya mempelajari dasar-dasarnya.
SK9
@ SK9: Tidak ada kesalahan seperti itu pada kode yang Anda posting. Saya memeriksanya beberapa kali dan menjalankannya sendiri, berfungsi dengan baik. Itu bahkan tidak bisa menyebabkan kesalahan ini (tidak ada referensi ke nama MAX_FIVE_FLUSH_KEY_INT). Posting traceback.
@ Thomas: Terima kasih telah menguji ini. Hmm, saya akan coba lagi. (Referensi yang dimaksud adalah salah ketik.) Anda mencoba file apa adanya? (Saya copy dan paste isi lengkap di atas.)
SK9
@ SK9: Saya bukan Thomas;) Dan ya, saya menyalin dan menempel semuanya, saya bahkan membiarkan nama file apa adanya. Sekali lagi, pelacakan balik akan membantu kami melakukan debug.
18

Python tidak memiliki preprocessor, juga tidak memiliki konstanta dalam arti tidak dapat diubah - Anda selalu dapat berubah (hampir, Anda dapat meniru properti objek konstan, tetapi melakukan ini demi konstanta jarang selesai dan tidak dianggap berguna) semuanya. Saat mendefinisikan sebuah konstanta, kami mendefinisikan sebuah nama dengan huruf besar-dengan-garis bawah dan menyebutnya sehari - "Kami semua menyetujui orang dewasa di sini", tidak ada orang waras yang akan mengubah sebuah konstanta. Kecuali tentu saja dia memiliki alasan yang sangat bagus dan tahu persis apa yang dia lakukan, dalam hal ini Anda tidak dapat (dan sebaiknya tidak) menghentikannya.

Tetapi tentu saja Anda dapat menentukan nama tingkat modul dengan nilai dan menggunakannya di modul lain. Ini tidak spesifik untuk konstanta atau apapun, baca di sistem modul.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

sumber
11

Dan tentu saja Anda bisa melakukan:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT
tony
sumber
3
import * secara umum tidak disarankan, tetapi konstanta manifes gaya-C yang banyak digunakan di seluruh basis kode adalah salah satu tempat yang tidak terlalu sulit untuk menggunakannya. Memberi nama mereka dalam ALL_CAPS atau dengan beberapa konvensi awalan yang mengurangi kemungkinan tabrakan dengan simbol lain menghilangkan keberatan utama idiom, dan jika tabrakan terjadi Anda selalu dapat kembali ke impor konvensional + gaya nama eksplisit (import a; a .MY_CONSTNAT), tidak seperti di C.
Russell Borogove
juga a.MY_CONSTNAT sedikit lebih lambat, itu karena juru bahasa mencari di satu namespace untuk nama 'a' dan kemudian di nama musuh kedua 'MY_CONSTNAT'
tony
7

Tentu, Anda dapat meletakkan konstanta Anda ke dalam modul terpisah. Sebagai contoh:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

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

Perhatikan bahwa sebagaimana dinyatakan di atas, A, Bdan Cadalah variabel, yaitu dapat diubah pada waktu berjalan.

NPE
sumber
5

Coba lihat Buat konstanta menggunakan modul "pengaturan"? dan Bisakah saya mencegah modifikasi objek dengan Python?

Tautan lain yang berguna: http://code.activestate.com/recipes/65207-constants-in-python/ memberi tahu kita tentang opsi berikut:

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'

Jadi Anda dapat membuat kelas seperti ini dan kemudian mengimpornya dari modul Anda contants.py. Ini akan memungkinkan Anda untuk memastikan bahwa nilai tidak akan berubah, dihapus.

Artsiom Rudzenka
sumber
Terima kasih untuk ini. Sebelum bertanya tentang SO saya mencari dan menemukan keduanya. :)
SK9
@ SK9 oh, maaf untuk duplikatnya
Artsiom Rudzenka
4

Sebagai alternatif untuk menggunakan pendekatan import yang dijelaskan dalam beberapa jawaban, lihat configparser modul .

Kelas ConfigParser mengimplementasikan bahasa parser file konfigurasi dasar yang menyediakan struktur yang mirip dengan apa yang akan Anda temukan di file Microsoft Windows INI. Anda dapat menggunakan ini untuk menulis program Python yang dapat disesuaikan oleh pengguna akhir dengan mudah.

Fredrik Pihl
sumber
2

Jika Anda benar-benar menginginkan konstanta, bukan hanya variabel yang tampak seperti konstanta, cara standar untuk melakukannya adalah dengan menggunakan kamus yang tidak dapat diubah. Sayangnya itu belum built-in, jadi Anda harus menggunakan resep pihak ketiga (seperti ini atau itu ).

vartec
sumber
2

buat file konstan dengan nama apapun seperti my_constants.py nyatakan konstan seperti itu

CONSTANT_NAME = "SOME VALUE"

Untuk mengakses konstanta dalam file impor kode Anda seperti itu

import my_constants as constant

dan akses nilai konstan sebagai -

constant.CONSTANT_NAME
rajanbhadauria
sumber