यदि आप एक ही उदाहरण के एक ही गुण को कई बार संदर्भित करते हैं, तो एक साधारण चाल इसे स्थानीय चर में संग्रहीत करना है।
आप एक तरह से सस्ते शुद्ध अजगर क्लोन बनाने के लिए, मूल वस्तु के साथ dict वस्तु का हिस्सा चाहते हैं:
class CheapClone(object):
def __init__(self, original):
self.__dict__ = original.__dict__
एक प्रति बनाई जा रही इस instrumented विशेषता का उपयोग के बारे में आधे की लागत की तरह और विशेषता लुकअप के रूप में कर रहे हैं सामान्य के रूप में तेज़।
मैपर एक उपकरण के बजाए एक निर्विवाद वर्ग के उदाहरण बनाने का एक तरीका भी हो सकता है। यदि मेरे पास कुछ समय है, तो मैं देख सकता हूं कि कितनी गहराई से यह माना जाता है कि जनसंख्या वाले उदाहरण साधन वर्ग के समान प्रकार के होते हैं।
एक त्वरित और गंदा तरीका मिला जो कम से कम कुछ हद तक 0.5.8 और 0.6 पर काम करता है। विरासत या अन्य सुविधाओं के साथ इसका परीक्षण नहीं किया जो बुरी तरह से बातचीत कर सकता है। साथ ही, यह कुछ गैर-सार्वजनिक एपीआई को छूता है, इसलिए संस्करणों को बदलते समय ब्रेकेज से सावधान रहें।
from sqlalchemy.orm.attributes import ClassManager, instrumentation_registry
class ReadonlyClassManager(ClassManager):
"""Enables configuring a mapper to return instances of uninstrumented
classes instead. To use add a readonly_type attribute referencing the
desired class to use instead of the instrumented one."""
def __init__(self, class_):
ClassManager.__init__(self, class_)
self.readonly_version = getattr(class_, 'readonly_type', None)
if self.readonly_version:
# default instantiation logic doesn't know to install finders
# for our alternate class
instrumentation_registry._dict_finders[self.readonly_version] = self.dict_getter()
instrumentation_registry._state_finders[self.readonly_version] = self.state_getter()
def new_instance(self, state=None):
if self.readonly_version:
instance = self.readonly_version.__new__(self.readonly_version)
self.setup_instance(instance, state)
return instance
return ClassManager.new_instance(self, state)
Base = declarative_base()
Base.__sa_instrumentation_manager__ = ReadonlyClassManager
प्रयोग उदाहरण:
class ReadonlyFoo(object):
pass
class Foo(Base, ReadonlyFoo):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
name = Column(String(32))
readonly_type = ReadonlyFoo
assert type(session.query(Foo).first()) is ReadonlyFoo
स्रोत
2010-02-24 02:27:53
दुर्भाग्य से उपयोग पैटर्न कई छोटी वस्तुओं में कई गणना है, इसलिए स्थानीय कैशिंग बहुत उपयोगी नहीं है। क्लोनिंग विचार वास्तव में जाने के रास्ते की तरह लगता है, त्वरित टिप के लिए धन्यवाद। आपकी अंतिम टिप्पणी बिल्कुल वही है जो मैं चाहूंगा: मैपर से 'अनजान' वर्ग बनाने के लिए कहें, क्योंकि मुझे पता है कि यह केवल पढ़ने के लिए है। – CarlS
धन्यवाद एक गुच्छा! मैं इसे आजमाने के लिए इंतजार नहीं कर सकता। – CarlS
मैंने मैपर हैक पर कुछ शुरुआती काम किया है और समय अंतर अंतरदायक हैं। मैं के लिए xrange में (500000): एक साधारण पाश के लिए foo = readonlyobj.attr_bar सामान्य उपकरण के साथ: 2.663 सेकेंड केवल पढ़ने के लिए नक्शाकार हैक साथ : 0.078 सेकेंड एक बहुत ही महत्वपूर्ण परिणाम imo है यही कारण है, इसलिए धन्यवाद फिर से। मैं अभी भी वास्तव में यह समझने की कोशिश कर रहा हूं कि यह कैसे काम करता है और यह थोड़ा अधिक गहराई में स्क्लेल्चेमी सीखने का एक शानदार तरीका साबित कर रहा है। – CarlS