Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
241 views
in Technique[技术] by (71.8m points)

python - The same method for class and instance

I have class Books and method select in it. Also there is an instance of that class called book. I want to be able to do both Books.select(where='...') and book.select(where='...'):

class Books():
    def select(obj, where):
        print(obj, where)

book = Books()
Books.select(where='asdf')
book.select(where='asdf')

The above obviously doesn't work, because select is an instance bound method:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    Books.select(where='asdf')
TypeError: select() takes exactly 2 arguments (1 given)

A working code:

class Books():
    @staticmethod
    def select(obj, where):
        print(obj, where)

book = Books()
Books.select(Books, where='asdf')
Books.select(book, where='asdf')

And i get:

vic@wic:~/projects/snippets$ python3 test.py 
<class '__main__.Books'> asdf
<__main__.Books object at 0x17fd6d0> asdf

But i have to manually pass the class or its instance as the first argument to the select method - not what i want.

If i make select a class method:

class Books():
    @classmethod
    def select(obj, where):
        print(obj, where)

book = Books()
Books.select(where='asdf')
book.select(where='asdf')

I always get a class as the first argument:

vic@wic:~/projects/snippets$ python3 test.py 
<class '__main__.Books'> asdf
<class '__main__.Books'> asdf

But i want to get an instance in the second case.

So, is there a way to accomplish what i want without manually passing the class/instance as the first argument to a static method?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use a descriptor:

class Select(object):
    def __get__(self,obj,objtype):
        x=objtype if obj is None else obj
        def select(where):
            print(x,where)
        return select
class Books(object):
    select=Select()

book = Books()
Books.select(where='asdf')
book.select(where='asdf')

yields

<class '__main__.Books'> asdf
<__main__.Books object at 0xb7696dec> asdf

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...