Hãy xem xét python (3.x) kịch bản:trăn nhập khẩu tròn một lần nữa (aka gì sai với thiết kế này)
main.py:
from test.team import team
from test.user import user
if __name__ == '__main__':
u = user()
t = team()
u.setTeam(t)
t.setLeader(u)
thử nghiệm/user.py:
from test.team import team
class user:
def setTeam(self, t):
if issubclass(t, team.__class__):
self.team = t
thử nghiệm/team.py:
from test.user import user
class team:
def setLeader(self, u):
if issubclass(u, user.__class__):
self.leader = u
Không w, tất nhiên, tôi đã nhập khẩu tròn và ImportError tuyệt vời.
Vì vậy, không phải là pythonista, tôi có ba câu hỏi. Trước hết:
i. Làm thế nào tôi có thể làm cho điều này hoạt động?
Và biết rằng một người nào đó chắc chắn sẽ nói "Thông tư nhập khẩu luôn cho biết vấn đề thiết kế", câu hỏi thứ hai là:
ii. Tại sao thiết kế này lại xấu?
Và cuối cùng, thứ ba:
iii. Điều gì sẽ là lựa chọn tốt hơn?
Để chính xác, việc kiểm tra kiểu như trên chỉ là một ví dụ, đó cũng là một lớp chỉ mục dựa trên lớp, cho phép nghĩa là. tìm tất cả người dùng là thành viên của một nhóm nghiên cứu (sử dụng lớp có nhiều lớp con, vì vậy chỉ số được tăng lên gấp đôi, cho người dùng nói chung và đối với từng lớp con cụ thể) hoặc tất cả các đội có sử dụng được coi là một thành viên
Edit:
Tôi hy vọng rằng ví dụ chi tiết hơn sẽ làm rõ những gì tôi cố gắng đạt được. File bỏ qua cho readibility (nhưng có file nguồn một 300KB làm tôi sợ bằng cách nào đó, vì vậy hãy giả sử rằng mỗi lớp là trong tập tin khác nhau)
# ENTITY
class Entity:
_id = None
_defs = {}
_data = None
def __init__(self, **kwargs):
self._id = uuid.uuid4() # for example. or randint(). or x+1.
self._data = {}.update(kwargs)
def __settattr__(self, name, value):
if name in self._defs:
if issubclass(value.__class__, self._defs[name]):
self._data[name] = value
# more stuff goes here, specially indexing dependencies, so we can
# do Index(some_class, name_of_property, some.object) to find all
# objects of some_class or its children where
# given property == some.object
else:
raise Exception('Some misleading message')
else:
self.__dict__[name] = value
def __gettattr__(self, name):
return self._data[name]
# USERS
class User(Entity):
_defs = {'team':Team}
class DPLUser(User):
_defs = {'team':DPLTeam}
class PythonUser(DPLUser)
pass
class PerlUser(DPLUser)
pass
class FunctionalUser(User):
_defs = {'team':FunctionalTeam}
class HaskellUser(FunctionalUser)
pass
class ErlangUser(FunctionalUser)
pass
# TEAMS
class Team(Entity):
_defs = {'leader':User}
class DPLTeam(Team):
_defs = {'leader':DPLUser}
class FunctionalTeam(Team):
_defs = {'leader':FunctionalUser}
và bây giờ một số sử dụng:
t1 = FunctionalTeam()
t2 = DLPTeam()
t3 = Team()
u1 = HaskellUser()
u2 = PythonUser()
t1.leader = u1 # ok
t2.leader = u2 # ok
t1.leader = u2 # not ok, exception
t3.leader = u2 # ok
# now , index
print(Index(FunctionalTeam, 'leader', u2)) # -> [t2]
print(Index(Team, 'leader', u2)) # -> [t2,t3]
Vì vậy, nó hoạt động tuyệt vời (chi tiết thực hiện được thừa nhận, nhưng không có gì phức tạp) bên cạnh điều nhập khẩu vòng tròn vô hại này.
Được coi là phương pháp hay để tận dụng các lớp học của bạn-- Nhóm/Người dùng. – snapshoe
Ngoài ra: hãy kiểm tra [thuộc tính] của python (http://docs.python.org/library/functions.html#property) để biết cách thay thế ưu tiên để khai báo các bộ định cư và getters. – intuited
@intuited: Tôi yêu trang trí, nhưng dường như nó không hoạt động tốt với __setattr__/__getattr__ (ví dụ ở trên là khá đơn giản) –