Nhận tên của lớp hiện tại?


102

Làm cách nào để lấy tên của lớp tôi đang học?

Thí dụ:

def get_input(class_name):
    [do things]
    return class_name_result

class foo():
    input = get_input([class name goes here])

Do bản chất của chương trình tôi đang giao tiếp (vistrails), tôi không thể sử dụng __init__()để khởi tạo input.

Câu trả lời:


158

obj.__class__.__name__ sẽ cung cấp cho bạn bất kỳ tên đối tượng nào, vì vậy bạn có thể làm điều này:

class Clazz():
    def getName(self):
        return self.__class__.__name__

Sử dụng:

>>> c = Clazz()
>>> c.getName()
'Clazz'

1
Tại sao đây không phải là câu trả lời được chấp nhận? CHỈNH SỬA: Ok Phạm vi của OP không bên trong, nó ở cấp lớp.
KomodoDave

6
@KomodoDave, bởi vì điều này là sai, ngay cả trong phạm vi phương thức. Khi bạn gọi getNametừ một lớp con, nó sẽ xuất ra tên lớp con. Sau đó, nó sẽ trở nên khó khăn nếu bạn REALLy muốn lớp bạn đang làm việc.
Kenet Jervet

@KenetJervet Ý của bạn là khi bạn gọi getNametừ một lớp cha, nó sẽ xuất ra tên lớp con? Ok ty vì đã chỉ ra điều đó.
Komodo: Lưu

5
Theo thuật ngữ OO, giải pháp (trả về tên lớp con thời gian chạy thực tế ngay cả khi getName()phương thức tình cờ được xác định trong lớp cha) là đúng.
sxc731

22

Trong phần thân của một lớp, tên lớp chưa được xác định, vì vậy nó không có sẵn. Bạn có thể không chỉ cần gõ tên của lớp? Có thể bạn cần nói thêm về vấn đề để chúng tôi tìm ra giải pháp cho bạn.

Tôi sẽ tạo một siêu kính để thực hiện công việc này cho bạn. Nó được gọi vào lúc tạo lớp (về mặt khái niệm ở cuối lớp: khối) và có thể thao tác với lớp đang được tạo. Tôi chưa kiểm tra cái này:

class InputAssigningMetaclass(type):
    def __new__(cls, name, bases, attrs):
        cls.input = get_input(name)
        return super(MyType, cls).__new__(cls, name, bases, newattrs)

class MyBaseFoo(object):
    __metaclass__ = InputAssigningMetaclass

class foo(MyBaseFoo):
    # etc, no need to create 'input'

class foo2(MyBaseFoo):
    # etc, no need to create 'input'

ĐỂ làm rõ những gì tôi đang cố gắng làm: Tôi cần tạo và khởi tạo một biến lớp, 'đầu vào', bên ngoài một phương thức . Tôi có một loạt các lớp nhỏ, mỗi lớp phải gọi 'get_input' bằng cách sử dụng tên lớp của chúng làm tham số. Tôi đang cố gắng tổng quát hóa điều này để tôi không cần phải đi đến từng lớp (sẽ có 100 hoặc lâu hơn) và nhập tên của lớp.
Jonathan Ginsburg

Được rồi, tôi đã cập nhật câu trả lời của mình bằng một kính đo có thể hữu ích.
Ned Batchelder

1
Những gì MyTypetrong superdòng InputAssigningMetaclassđề cập đến?
A.Wan

16

Bạn có thể truy cập nó bằng các thuộc tính private của lớp:

cls_name = self.__class__.__name__

BIÊN TẬP:

Như đã nói Ned Batcheler, điều này sẽ không hoạt động trong phần thân của lớp, nhưng nó sẽ ở trong một phương thức.


11

Đã giới thiệu PEP 3155__qualname__ , được triển khai bằng Python 3.3.

Đối với các hàm và lớp cấp cao nhất, __qualname__thuộc tính bằng __name__thuộc tính. Đối với các lớp, phương thức và hàm lồng nhau, __qualname__thuộc tính chứa một đường dẫn chấm dẫn đến đối tượng từ cấp cao nhất của mô-đun.

Nó có thể truy cập từ bên trong định nghĩa của một lớp hoặc một hàm, chẳng hạn như:

class Foo:
    print(__qualname__)

sẽ in hiệu quả Foo. Bạn sẽ nhận được tên đủ điều kiện (không bao gồm tên của mô-đun), vì vậy bạn có thể muốn tách nó trên .ký tự.

Tuy nhiên, không có cách nào để có được một xử lý thực tế trên lớp đang được định nghĩa.

>>> class Foo:
...     print('Foo' in globals())
... 
False

7

CHỈNH SỬA: Có, bạn có thể; nhưng bạn phải gian lận: Tên lớp hiện đang chạy hiện diện trên ngăn xếp cuộc gọi và tracebackmô-đun cho phép bạn truy cập ngăn xếp.

>>> import traceback
>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> class foo(object):
...      _name = traceback.extract_stack()[-1][2]
...     input = get_input(_name)
... 
>>> 
>>> foo.input
'sbb'

Tuy nhiên, tôi sẽ không làm điều này; Câu trả lời ban đầu của tôi vẫn là sở thích của riêng tôi như một giải pháp. Câu trả lời ban đầu:

Có lẽ giải pháp đơn giản nhất là sử dụng một người trang trí, tương tự như câu trả lời của Ned liên quan đến kính thiên thạch, nhưng ít mạnh hơn (người trang trí có khả năng ma thuật đen, nhưng kính thiên văn có khả năng ma thuật đen cổ đại, huyền bí )

>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> def inputize(cls):
...     cls.input = get_input(cls.__name__)
...     return cls
... 
>>> @inputize
... class foo(object):
...     pass
... 
>>> foo.input
'sbb'
>>> 

1
import sys

def class_meta(frame):
    class_context = '__module__' in frame.f_locals
    assert class_context, 'Frame is not a class context'

    module_name = frame.f_locals['__module__']
    class_name = frame.f_code.co_name
    return module_name, class_name

def print_class_path():
    print('%s.%s' % class_meta(sys._getframe(1)))

class MyClass(object):
    print_class_path()

1

Tôi nghĩ, nó phải như thế này:

    class foo():
        input = get_input(__qualname__)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.