2013-11-01 29 views
7

Dưới đây, base_id_id là biến lớp và được chia sẻ giữa tất cả các lớp con.
Có cách nào để tách chúng thành từng lớp không?ghi đè biến lớp trong python?

from itertools import count 

class Parent(object): 
    base_id = 0 
    _id = count(0) 

    def __init__(self): 
     self.id = self.base_id + self._id.next() 


class Child1(Parent): 
    base_id = 100 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child1:', self.id 

class Child2(Parent): 
    base_id = 200 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child2:', self.id 

c1 = Child1()     # 100 
c2 = Child2()     # 201 <- want this to be 200 
c1 = Child1()     # 102 <- want this to be 101 
c2 = Child2()     # 203 <- want this to be 201 
+0

Có lý do cụ thể nào khiến bạn muốn hàng trăm chữ số đại diện cho lớp không? Còn nếu bạn nhận được hơn 100 trường hợp? Sau đó, bạn sẽ có chồng lên nhau. Bạn sẽ thấy ID ở đâu và có cách nào tốt hơn để phân biệt giữa các lớp so với sử dụng ID? (Có lẽ bạn có thể hiển thị một số thông tin bổ sung, ví dụ.) – jpmc26

+1

Điều đó không thực sự quan trọng ở đây; ngay cả khi eugene đã thay đổi ID thành 2-tuple (ví dụ: (1,0), (1,1), (1,2) ... cho 'Child1') thì vấn đề tạo bộ đếm độc lập vẫn còn. –

Trả lời

3

Nếu bạn không muốn vi phạm các nguyên tắc DRY như falsetru gợi ý, bạn sẽ cần phải sử dụng metaclasses. Tôi đã nghĩ đến việc viết một cái gì đó lên, nhưng there's already a good long description of metaclasses on SO, vì vậy hãy kiểm tra nó ra.

Metaclasses, trong ngắn hạn, cho phép bạn kiểm soát việc tạo lớp con.

Về cơ bản, những gì bạn cần làm là khi tạo lớp con của Parent, thêm thành viên _id vào phân lớp mới được tạo.

2

Như bạn đã nói trong câu hỏi, _id được chia sẻ bởi cha mẹ và tất cả các lớp con. Xác định _id cho mọi lớp học cho trẻ em.

from itertools import count 

class Parent(object): 
    base_id = 0 
    _id = count(0) 

    def __init__(self): 
     self.id = self.base_id + self._id.next() 


class Child1(Parent): 
    base_id = 100 
    _id = count(0) # <------- 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child1:', self.id 

class Child2(Parent): 
    base_id = 200 
    _id = count(0) # <------- 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child2:', self.id 

c1 = Child1()     # 100 
c2 = Child2()     # 200 
c1 = Child1()     # 101 
c2 = Child2()     # 201 

CẬP NHẬT

Sử dụng metaclass:

class IdGenerator(type): 
    def __new__(mcs, name, bases, attrs): 
     attrs['_id'] = count(0) 
     return type.__new__(mcs, name, bases, attrs) 

class Parent(object): 
    __metaclass__ = IdGenerator 
    base_id = 0 
    def __init__(self): 
     self.id = self.base_id + next(self._id) 
4

thông số Nếu bạn thực sự cần phải sử dụng ID theo cách này, sử dụng:

class Parent(object): 
    def __init__(self, id): 
     self.id = id 

class Child1(Parent): 
    _id_counter = count(0) 
    def __init__(self): 
     Parent.__init__(self, 100 + self._id_counter.next()) 
     print 'Child1:', self.id 

, vv

này giả định bạn sẽ không được xây dựng các trường hợp Parent trực tiếp, nhưng trông hợp lý với bạn mã ví dụ.

Các vấn đề liên quan