2012-07-10 33 views
21

Tôi có một lớp cơ sở Person và các lớp dẫn xuất ManagerEmployee. Bây giờ, những gì tôi muốn biết là đối tượng được tạo là Manager hoặc Employee.cách lấy tên lớp có nguồn gốc từ lớp cơ sở

Người được đưa ra như belows:

from Project.CMFCore.utils import getToolByName 
schema = getattr(Person, 'schema', Schema(())).copy() + Schema((TextField('FirstName', required = True, widget = StringWidget(label='First Name', i18n_domain='project')), TextField('Last Name', required = True, widget = StringWidget(label='Last Name', i18n_domain='i5', label_msgid='label_pub_city')) 
class Manager(BaseContent): 
    def get_name(self): 
    catalog = getToolByName(self, "portal_catalog") 
     people = catalog(portal_type='Person') 
     person={} 
     for object in people: 
     fname = object.firstName 
     lname = object.lastName 
     person['name'] = fname+' '+ lname 
     # if the derived class is Employee then i would like go to the method title of employee and if its a Manager then go to the title method of Manager 
     person['post'] = Employee/Manager.title() 
     return person 

Đối với quản lý và người lao động họ giống như (nhân viên cũng tương tự nhưng một số phương pháp khác nhau)

from Project.Person import Person 
class Manager(Person): 
    def title(self): 
     return "Manager" 

Đối với người lao động tiêu đề là 'nhân viên' . Khi tôi tạo một Person, hoặc là Manager hoặc Employee. Khi tôi nhận được đối tượng người, lớp đó là Person nhưng tôi muốn biết liệu nó có phải là từ lớp 'Manager' hoặc 'Employee'.

+0

Bạn có thể đưa ra một số mã trình bày những gì bạn muốn làm chính xác không? – SuperSaiyan

Trả lời

4

Không chắc chắn chính xác rằng tôi hiểu những gì bạn đang yêu cầu, nhưng bạn có thể sử dụng x.__class__.__name__ để truy xuất tên lớp dưới dạng chuỗi, ví dụ:

class Person: 
    pass 

class Manager(Person): 
    pass 

class Employee(Person): 
    pass 

def get_class_name(instance): 
    return instance.__class__.__name__ 

>>> m = Manager() 
>>> print get_class_name(m) 
Manager 
>>> print get_class_name(Employee()) 
Employee 

Hoặc, bạn có thể sử dụng isinstance để kiểm tra các loại khác nhau:

>>> print isinstance(m, Person) 
True 
>>> print isinstance(m, Manager) 
True 
>>> print isinstance(m, Employee) 
False 

Vì vậy, bạn có thể làm một cái gì đó như thế này:

def handle_person(person): 
    if isinstance(person, Manager): 
     person.read_paper()  # method of Manager class only 
    elif isinstance(person, Employee): 
     person.work_hard()  # method of Employee class only 
    elif isinstance(person, Person): 
     person.blah()   # method of the base class 
    else: 
     print "Not a person" 
6

đối tượng Python cung cấp một thuộc tính __class__ mà các cửa hàng loại được sử dụng để tạo đối tượng đó. Điều này lần lượt cung cấp một thuộc tính __name__ có thể được sử dụng để có được tên của loại như là một chuỗi. Vì vậy, trong trường hợp đơn giản:

class A(object): 
    pass 
class B(A): 
    pass 

b = B() 
print b.__class__.__name__ 

sẽ cung cấp cho:

'B'

Vì vậy, nếu tôi làm theo câu hỏi của bạn một cách chính xác bạn sẽ làm gì:

m = Manager() 
print m.__class__.__name__ 
'Manager' 
+0

Tôi nghĩ bạn đang trả lời đúng câu hỏi. – yaobin

27

Tôi không biết nếu đây là những gì bạn muốn và cách bạn muốn nó được triển khai, nhưng đây là một thử:

>>> class Person(object): 
    def _type(self): 
     return self.__class__.__name__ 


>>> p = Person() 
>>> p._type() 
'Person' 
>>> class Manager(Person): 
    pass 

>>> m = Manager() 
>>> m._type() 
'Manager' 
>>> 

Ưu điểm: chỉ một định nghĩa của phương pháp _type.

+0

Tính gọn gàng. Sử dụng tốt đầu ra tương tác. –

+0

Rất cám ơn .. Đây là những gì tôi đang tìm kiếm! –

4

Cách tốt nhất để "thực hiện việc này" là không thực hiện. Thay vào đó, hãy tạo các phương thức trên Person được ghi đè lên Trình quản lý hoặc Nhân viên, hoặc cung cấp cho các lớp con các phương thức riêng của chúng để mở rộng lớp cơ sở.

class Person(object): 
    def doYourStuff(self): 
     print "I'm just a person, I don't have anything to do" 

class Manager(object): 
    def doYourStuff(self): 
     print "I hereby manage you" 

class Employee(object): 
    def doYourStuff(self): 
     print "I work long hours" 

Nếu bạn thấy mình cần biết trong lớp cơ sở mà lớp con đang được khởi tạo, chương trình của bạn có thể có lỗi thiết kế. Bạn sẽ làm gì nếu một người khác sau đó mở rộng Người để thêm một phân lớp mới được gọi là Nhà thầu? Người sẽ làm gì khi lớp con không phải là bất kỳ lựa chọn thay thế mã hóa cứng nào mà nó biết?

+0

Nghi ngờ đây là "cách tốt nhất" hoặc OP có thiết kế bị hỏng. Đơn giản để thực hiện như được hiển thị trong [câu trả lời] (http://stackoverflow.com/a/11408458/355230) trong đó lớp cơ sở có một phương thức mà tất cả các lớp con có thể sử dụng (cho bất kỳ mục đích nào mà chúng chọn). – martineau

0

Trong ví dụ của bạn, bạn không cần phải biết các lớp học, bạn chỉ cần gọi phương thức bằng cách tham khảo các ví dụ lớp:

# if the derived class is Employee then i would like go to the method title 
# of employee and if its a Manager then go to the title method of Manager 
person['post'] = object.title() 

Nhưng đừng sử dụng object như một tên biến, bạn ẩn các built- trong tên.

3

Bạn có đang tìm kiếm nội dung như thế này không?

>>> class Employee: 
...  pass 
... 
>>> class Manager(Employee): 
...  pass 
... 
>>> e = Employee() 
>>> m = Manager() 
>>> print e.__class__.__name__ 
Employee 
>>> print m.__class__.__name__ 
Manager 
>>> e.__class__.__name__ == 'Manager' 
False 
>>> e.__class__.__name__ == 'Employee' 
True 
Các vấn đề liên quan