एक आत्म परियोजना के लिए के लिए अजगर की स्ट्रिंग होना शामिल कार्यक्षमता को दोहराने के लिए प्रयास कर रहा है, मैं की तरह कुछ करना चाहता था:गैर तार
class Species(object): # immutable.
def __init__(self, id):
# ... (using id to obtain height and other data from file)
def height(self):
# ...
class Animal(object): # mutable.
def __init__(self, nickname, species_id):
self.nickname = nickname
self.species = Species(id)
def height(self):
return self.species.height()
आप देख सकते हैं, मैं वास्तव में एक से अधिक उदाहरण की जरूरत नहीं है प्रति आईडी प्रजातियां (आईडी), लेकिन जब भी मैं उस आईडी के साथ एक एनिमल ऑब्जेक्ट बना रहा हूं, तो मैं एक बार बनाउंगा, और मुझे शायद Animal(somename, 3)
कहने के लिए कई कॉल की आवश्यकता होगी।
कि हल करने के लिए, मैं क्या करने की कोशिश कर रहा हूँ एक वर्ग बनाने के लिए इतना है कि यह के 2 उदाहरण के लिए, के ए और बी मान लीजिए है, तो निम्न हमेशा सत्य है:
(a == b) == (a is b)
यह कुछ है कि पायथन स्ट्रिंग अक्षर के साथ करता है और इसे इंटर्नशिप कहा जाता है। उदाहरण:
a = "hello"
b = "hello"
print(a is b)
कि प्रिंट सच (जब तक स्ट्रिंग काफी कम है अगर हम अजगर खोल सीधे उपयोग कर रहे हैं) निकलेगा।
मैं केवल अनुमान लगा सकता हूं कि कैसे सीपीथन यह करता है (इसमें शायद कुछ सी जादू शामिल है) इसलिए मैं इसका अपना संस्करण कर रहा हूं। अब तक मुझे मिल गया है:
class MyClass(object):
myHash = {} # This replicates the intern pool.
def __new__(cls, n): # The default new method returns a new instance
if n in MyClass.myHash:
return MyClass.myHash[n]
self = super(MyClass, cls).__new__(cls)
self.__init(n)
MyClass.myHash[n] = self
return self
# as pointed out on an answer, it's better to avoid initializating the instance
# with __init__, as that one's called even when returning an old instance.
def __init(self, n):
self.n = n
a = MyClass(2)
b = MyClass(2)
print a is b # <<< True
मेरे प्रश्न हैं:
क) मेरी समस्या भी हल करने के लायक है? चूंकि मेरी इच्छित प्रजाति वस्तु काफी हल्का वजन होनी चाहिए और अधिकतम मात्रा में पशु को बुलाया जा सकता है, बल्कि सीमित (एक पॉकेटम गेम की कल्पना करें: 1000 से अधिक उदाहरण, शीर्ष)
बी) यदि यह है, तो यह है मेरी समस्या को हल करने के लिए वैध दृष्टिकोण?
सी) यदि यह मान्य नहीं है, तो क्या आप इसे हल करने के लिए एक सरल/क्लीनर/अधिक पाइथोनिक तरीके से विस्तृत कर सकते हैं?
आप के अजगर के क्रियान्वयन में कोड का एक काफी समान तरह देख सकते हैं 'functools.lru_cache' के लिए विभिन्न [' रैपर '] (https://hg.python.org/cpython/file/3.5/Lib/functools.py#l453)। जैसे ही होता है, जब वे काम परमाणु होते हैं, तो वे "परमाणु" संचालन के लिए लॉक नहीं होते हैं, जो उपर्युक्त मेरी टिप्पणी का समर्थन करता है, लेकिन वे इसका उपयोग करते हैं "कैश से लॉक होने की कोशिश करें, अगर विफल हो, लॉक रिलीज करें, महंगा प्रदर्शन करें कार्य, लॉक पुनः प्राप्त करें और यदि कैश नहीं किया गया तो कैश अपडेट करें "कैश आकार के लिए ऊपर इस्तेमाल किया गया पैटर्न सीमित है (और संचालन के समूह परमाणु रूप से प्रदर्शन किया जाना चाहिए)। – ShadowRanger