2017-01-29 39 views
8

Oyun motoru, oyuncuları tanımlamak için uniqueid salt okunur özelliği olan bir Player sınıfı sağlar. Ben oyuncu sorgulayabilir, böylece böyle onunla bir SQLAlchemy en Column içine bu "dönüştürmek" istiyorum:Salt okunur bir salt okunur özelliği, aynı değere sahip bir sütun ile geçersiz kılma

class Player(game.Player, db.Model): 
    _uniqueid = Column('uniqueid', String(21), unique=True, nullable=False) 

    def __init__(self, index, **kwargs): 
     game.Player.__init__(index) # initializes uniqueid 
     db.Model.__init__(_uniqueid=self.uniqueid, **kwargs) 

Sonraki Ben istiyorum:

query = session.query(Player).filter(Player.uniqueid=='STEAM_0:0:1234567') 
player = query.one_or_none() 
if player is None: 
    player = Player(uniqueid='STEAM_0:0:1234567') 

İşte benim sınıf şu anda böyle görünüyor _uniqueid için bir salt okunur arabirim oluşturmak, böylece API kullanıcıları artık değişkene yazamazlar (iyi, _uniqueid aracılığıyla olabilir, ancak erişim özel olmayan uniqueid aracılığıyla olması gerektiğinden bu onların sorumluluğundadır).

Ben yenisi ile orijinal uniqueid ağır basan düşünüyorum:

@property 
def uniqueid(self): 
    return self._uniqueid 

Bu ve onlar kasten özel birine erişmek sürece yazmadan gelen kimseyi engelleyen "gizler" orijinal _uniqueid, salt okunur (Onu dokümantasyonda bile listelemem, sadece özel olmayanı göstereceğim).

tek sorun bu tamamen benim __init__ 'ın _uniqueid=self.uniqueidyeni oltalarını, değil eski birini kullanarak nedeniyle self.uniqueid için çalışmaz yani eskisini geçersiz kılar olmasıdır.

Özetle, istediğim, salt okunur bir özelliği SQLAlchemy ile sorgulamak için kullanılabilecek salt okunur bir öğeye dönüştürmektir. Bu mümkün mü ve nasıl yapılır?

+0

Bu büyük olasılıkla 'game.Player.uniqueid' nasıl uygulandığına bağlıdır. Örnek sözlüğüne ne yazıyor? Veritabanından bir 'Player' örneğini yeniden hidrate etmeniz gerektiğinde değeri nasıl belirlersiniz? Bu üçüncü parti kütüphaneleri için akılda tutulması zor olabileceğinden, genellikle model sınıflarını ve bunun gibi üçüncü parti sınıflarını karıştırmayı önermiyorum. – univerio

+0

@univerio Sadece bazı C sihirlerini kullanan salt okunur bir özellik. Temelde bir "player_join" olayı gerçekleştiğinde, oyun motoru katılan oyuncunun 'index' i ile birlikte gelir ve 'player = game.Player (index)' işlevi, bundan sonra 'uniqueid' özelliği okunabilen bir nesne verir. . –

+0

Ama 'uniqueid' için gerçek veriler nerede saklanır? Dizin'den hesaplandığını mı söylüyorsun? Ve bir oyuncuyu rehidrate etmek için ihtiyacınız olan şey onun endeksi mi? – univerio

cevap

1

game.Player ürününe erişmek için super kullanabilirsiniz. Biz Cython ile oluşturulan basit bir C uzantısı türünü kullanarak test edebilirsiniz:

# game.pyx 
cdef class Player: 
    cdef int index; 

    def __init__(self, index): 
     self.index = index 

    @property 
    def uniqueid(self): 
     return "foo" 


# test.py 
class Player(game.Player, Base): 
    __tablename__ = "player" 

    id = Column(Integer, primary_key=True) 
    _uniqueid = Column('uniqueid', String(21), unique=True, nullable=False) 

    def __init__(self, index, **kwargs): 
     game.Player.__init__(self, index) # initializes uniqueid 
     Base.__init__(self, _uniqueid=super().uniqueid, **kwargs) 

    @property 
    def uniqueid(self): 
     return self._uniqueid 

print(Player(1).uniqueid) # "foo" 

Çünkü C uzatma türlerinden devralmak incinebilirliğin, şu ya da game.Player tipi kullanan tam olarak ne C büyü bağlı çalışmıyor olabilir. o veritabanından örneklerini yüklediğinde ORM __init__ atlar çünkü Ayrıca

, sen game.Player türünü başlatmak amacıyla load olay kanca gerekecek.

+0

Maalesef, bu soruyu tamamen unutmuşum gibi görünüyor ... Kabul edildi ve şimdi kestim, bu gerçekten de * çalışıyor. –