2010-03-26 16 views
13

Tôi đang viết một lớp học để chèn người dùng vào một cơ sở dữ liệu, và trước khi tôi nhận được quá xa trong, tôi chỉ muốn chắc chắn rằng cách tiếp cận OO của tôi là sạch:Đúng cách để thiết lập các biến trường hợp đối tượng

class User(object): 

    def setName(self,name): 

     #Do sanity checks on name 
     self._name = name 

    def setPassword(self,password): 

     #Check password length > 6 characters 
     #Encrypt to md5 
     self._password = password 

    def commit(self): 

     #Commit to database 

>>u = User() 
>>u.setName('Jason Martinez') 
>>u.setPassword('linebreak') 
>>u.commit() 

Đây có phải là phương pháp phù hợp không? Tôi có nên khai báo các biến lớp lên trên không? Tôi có nên sử dụng _ trước tất cả các biến lớp để đặt chúng ở chế độ riêng tư không?

Cảm ơn bạn đã trợ giúp.

+0

Không có biến lớp nào trong mã của bạn. Cân nhắc cập nhật tiêu đề của bạn. –

+0

Bạn đang sử dụng hướng dẫn nào để học Python. Điều này cần được bảo hiểm. Vì nó không phải là, tôi muốn biết những gì bạn đang hướng dẫn sử dụng. –

+0

"biến đối tượng" được gọi là "thuộc tính" trong Python –

Trả lời

19

Nó thường đúng, AFAIK, nhưng bạn có thể làm sạch nó lên với properties.

class User(object): 

    def _setName(self, name=None): 
     self._name = name 

    def _getName(self): 
     return self._name 

    def _setPassword(self, password): 
     self._password = password 

    def _getPassword(self): 
     return self._password 

    def commit(self): 
     pass 

    name = property(_getName, _setName) 
    password = property(_getPassword, _setPassword) 

>>u = User() 
>>u.name = 'Jason Martinez' 
>>u.password = 'linebreak' 
>>u.commit() 

Cũng có một cú pháp dựa trên trang trí tiện lợi, tài liệu cũng giải thích điều đó.

+0

Điều này thực sự hữu ích. Cảm ơn bạn. – ensnare

+1

Tôi nhận thấy rằng hàm tạo của bạn đã chấp nhận một đối số 'name' bắt buộc, vì vậy việc sử dụng ví dụ của bạn về' User() 'sẽ ném một lỗi. Tôi đã chỉnh sửa ví dụ của mình để mặc định 'name' thành' None' để tránh điều này, nhưng bạn có thể muốn cung cấp quá trình triển khai thực hiện quá tải mà không có đối số nào cả. – bcherry

+0

Có, cảm ơn bạn! – ensnare

3

Không có biến lớp nào trong mã đó, chỉ các thuộc tính mẫu. Và sử dụng properties thay vì người truy cập. Và làm tạo ra các ví dụ thuộc tính trong initializer, tốt nhất từ ​​các giá trị thông qua tại:

class User(object): 
    def __init__(self, name, password='!!'): 
    self.name = name 
    self.password = password 

    ... 
+0

Cảm ơn phản hồi. Tôi không chắc chắn những gì thuộc tính được nhưng tôi sẽ đọc lên. Đối tượng User có rất nhiều biến, 50 hoặc hơn, vì vậy tôi nghĩ rằng sẽ có quá nhiều thứ để truyền vào hàm tạo, phải không? Tôi biết hiện không có biến lớp nào trong mã. Ý tôi là, tôi có nên tạo các biến lớp này không? Cảm ơn. – ensnare

+0

Không bao giờ, sử dụng biến lớp khi giá trị cần thay đổi từ ví dụ này sang ví dụ khác. –

7

sử dụng một _ không đặt thuộc tính của bạn ở chế độ riêng tư: đó là quy ước nói rằng đó là thuộc tính nội bộ và không nên trong trường hợp bình thường được truy cập bằng mã bên ngoài. Với mã của bạn nó cũng có nghĩa là mật khẩu và tên chỉ đọc.

Tôi khuyên bạn nên sử dụng trình khởi tạo cho lớp của bạn để khởi tạo thuộc tính của bạn, ngay cả khi giá trị mặc định như Không: nó sẽ giúp mọi thứ dễ dàng hơn trong phương pháp bạn sẽ không phải kiểm tra sự tồn tại của các thuộc tính _name và _password (với hasattr).

Sử dụng Pylint trên mã của bạn.

2

Những người khác đã chỉ ra rằng: tránh sử dụng bộ định vị và getters và sử dụng truy cập thuộc tính đơn giản nếu bạn không cần thực hiện thêm logic khi nhận/thiết lập thuộc tính của mình. Nếu bạn cần thêm logic thì hãy sử dụng các thuộc tính.

Nếu bạn có nhiều tham số để gửi một initializer dụ xem xét sử dụng đối tượng riêng biệt hoặc từ điển nắm giữ tất cả các thông số:

>>> class User(object): 
...  def __init__(self, params): 
...   self.__dict__.update(params) 
... 

>>> params = { 
...  'username': 'john', 
...  'password': 'linebreak', 
...  } 
>>> user = User(params) 
>>> user.username 
'john' 
>>> user.password 
'linebreak' 

T.B. Trong trường hợp của bạn, bạn không cần phải khai báo các thuộc tính của bạn ở cấp lớp. Thường được thực hiện nếu bạn muốn chia sẻ cùng một giá trị trên tất cả các phiên bản lớp:

>>> class User(object): 
...  type = 'superuser' 
... 
>>> user = User() 
>>> user2 = User() 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'superuser' 
>>> 
>>> user2.type = 'instance superuser' 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'instance superuser' 
>>> User.type 
'superuser' 
Các vấn đề liên quan