我根據讀取的內容編寫了一些代碼here,here和here。嘗試使用metaclasses創建只讀插槽
#! /usr/bin/env python3
class ROSlotsType(type):
def __new__(cls, name, bases, namespace, **kwds):
roprops = namespace.pop("__roslots__")
namespace["__slots__"] = tuple(("_" + propname) for propname in roprops)
for propname in roprops:
namespace[propname] = property(lambda self: getattr(self, "_" + propname)) # can't use self.__dict__ since it doesn't exist
return type.__new__(cls, name, bases, namespace)
class Location(metaclass = ROSlotsType):
__roslots__ = ["lat", "lon", "alt"]
def __init__(self, lat, lon, alt = 0):
self._lat = lat ; self._lon = lon ; self._alt = alt
def __repr__(self):
return "Location({}, {}, {})".format(self._lat, self._lon, self._alt)
place = Location(25.282, 82.956, 77.0)
print("Created object {}".format(place))
print("Accessing its attributes:", place.lat, place.lon, place.alt)
print("Trying to access its __dict__...")
try: place.__dict__
except:
print("Caught exception; object has only __slots__: {}".format(place.__slots__))
print("Trying to set new property...")
try: place.name = "Varanasi"
except:
print("Caught exception; cannot add new property")
print("Trying to modify read-only property...")
try: place.alt += 1
except:
print("Caught exception; cannot modify read-only property")
執行上面給出:
Created object Location(25.282, 82.956, 77.0)
Accessing its attributes: 77.0 77.0 77.0
Trying to access its __dict__...
Caught exception; object has only __slots__: ('_lat', '_lon', '_alt')
Trying to set new property...
Caught exception; cannot add new property
Trying to modify read-only property...
Caught exception; cannot modify read-only property
的插槽和只讀行爲做工精細,但顯然有一些問題與物業干將,因爲雖然__repr__
它採用_lat
和_lon
是直接給出正確的值時,使用place.lat
和place.lon
的屬性訪問取而代之的值爲place.alt
。
請告訴我我的代碼有什麼問題以及如何解決它。
在這種特殊情況下,我可以建議'namespace [propname] = property(operator.attrgetter('_'+ propname))'?這裏也值得一提'functools.partial',儘管不幸的是這次不是我們想要綁定的第一個參數。 –