Как избежать явного " я " в Python?
Я изучал Python, следуя некоторым , С которым Pygame учебники.
там я нашел широкое использование ключевого слова self, и исходя из преимущественно Java фона, я нахожу, что я постоянно забываю ввести self. Например, вместо self.rect.centerx Я бы типа rect.centerx, потому что для меня rect уже является переменной-членом класса.
параллель Java, которую я могу придумать для этой ситуации, имеет префикс всех ссылок на переменные-члены с этой.
Я застрял префикс всех переменных-членов с self, или есть способ объявить их, что позволит мне избежать этого?
даже если то, что я предлагаю не весть, Я все же хотел бы знать, если это возможно.
Я взглянул на эти связанные так вопросы, но они не совсем отвечают на то, что я есть после:
Python-зачем использовать "self" в классе?- почему вам нужно явно иметь аргумент "self" в метод Python?
10 ответов:
Python требует указания self. в результате никогда не возникает путаницы в отношении того, что является членом, а что нет, даже без полного определения класса. Это приводит к полезным свойствам, таким как: вы не можете добавлять элементы, которые случайно затеняют не-члены и тем самым нарушают код.
один крайний пример: вы можете написать класс без каких-либо знаний о том, какие базовые классы он может иметь, и всегда знать, получаете ли Вы доступ к члену или нет:
class A(some_function()): def f(self): self.member = 42 self.method()Это полное код! (some_function возвращает тип, используемый в качестве базы.)
другой, где методы класса динамически в составе:
class B(object): pass print B() # <__main__.B object at 0xb7e4082c> def B_init(self): self.answer = 42 def B_str(self): return "<The answer is %s.>" % self.answer # notice these functions require no knowledge of the actual class # how hard are they to read and realize that "members" are used? B.__init__ = B_init B.__str__ = B_str print B() # <The answer is 42.>помните, что оба этих примера экстремальны, и вы не будете видеть их каждый день, и я не предлагаю вам часто писать такой код, но они четко показывают, что аспекты себя явно требуются.
на самом деле
selfЭто не ключевое слово, это просто имя, условно данное первому параметру методов экземпляра в Python. И этот первый параметр нельзя пропустить, так как это единственный механизм, который метод имеет, чтобы знать, какой экземпляр вашего класса он вызывается.
вы можете использовать любое имя, например
class test(object): def function(this, variable): this.variable = variableили даже
class test(object): def function(s, variable): s.variable = variableно вы застряли с использованием имени для области.
да, вы всегда должны указывать
self, потому что явное лучше, чем неявное, в соответствии с философией python.вы также узнаете, что способ программирования на python очень отличается от способа программирования на java, следовательно, использование
selfимеет тенденцию уменьшаться, потому что вы не проецируете все внутри объекта. Скорее, вы делаете более широкое использование функции уровня модуля, которая может быть лучше протестирована.кстати. Я ненавидел его сначала, теперь я ненавижу противоположный. то же самое для управления потоком с отступом.
self является частью синтаксиса python для доступа к членам объектов, поэтому я боюсь, что вы застряли с ним
"self" является обычным заполнителем текущего экземпляра объекта класса. Он используется, когда вы хотите ссылаться на свойство объекта или поле или метод внутри класса, как если бы вы ссылались на "себя". Но чтобы сделать его короче, кто-то в области программирования Python начал использовать "self" , другие области используют "this", но они делают это как ключевое слово, которое нельзя заменить. Я скорее использовал "его", чтобы увеличить читаемость кода. Одна из хороших вещей в Python - у вас есть свобода выбора собственного заполнителя для экземпляра объекта, отличного от"self". Пример для себя:
class UserAccount(): def __init__(self, user_type, username, password): self.user_type = user_type self.username = username self.password = encrypt(password) def get_password(self): return decrypt(self.password) def set_password(self, password): self.password = encrypt(password)теперь мы заменим 'self' на 'its':
class UserAccount(): def __init__(its, user_type, username, password): its.user_type = user_type its.username = username its.password = encrypt(password) def get_password(its): return decrypt(its.password) def set_password(its, password): its.password = encrypt(password)что сейчас более читаемо?
предыдущие ответы-это все в основном варианты "вы не можете" или "вы не должны". Хотя я согласен с последним мнением, вопрос остается без ответа.
import numpy as np class MyFunkyGaussian() : def __init__(self, A, x0, w, s, y0) : self.A = float(A) self.x0 = x0 self.w = w self.y0 = y0 self.s = s # The correct way, but subjectively less readable to some (like me) def calc1(self, x) : return (self.A/(self.w*np.sqrt(np.pi))/(1+self.s*self.w**2/2) * np.exp( -(x-self.x0)**2/self.w**2) * (1+self.s*(x-self.x0)**2) + self.y0 ) # The correct way if you really don't want to use 'self' in the calculations def calc2(self, x) : # Explicity copy variables A, x0, w, y0, s = self.A, self.x0, self.w, self.y0, self.s sqrt, exp, pi = np.sqrt, np.exp, np.pi return ( A/( w*sqrt(pi) )/(1+s*w**2/2) * exp( -(x-x0)**2/w**2 ) * (1+s*(x-x0)**2) + y0 ) # Probably a bad idea... def calc3(self, x) : # Automatically copy every class vairable for k in self.__dict__ : exec(k+'= self.'+k) sqrt, exp, pi = np.sqrt, np.exp, np.pi return ( A/( w*sqrt(pi) )/(1+s*w**2/2) * exp( -(x-x0)**2/w**2 ) * (1+s*(x-x0)**2) + y0 ) g = MyFunkyGaussian(2.0, 1.5, 3.0, 5.0, 0.0) print(g.calc1(0.5)) print(g.calc2(0.5)) print(g.calc3(0.5))третий пример - т. е. с помощью
for k in self.__dict__ : exec(k+'= self.'+k)в основном то, что вопрос на самом деле просит, но позвольте мне уточнить, что я не думаю, что это вообще хорошая идея.для получения дополнительной информации и способов перебора переменных класса, или даже функции, ответы и обсуждения этот вопрос. Для обсуждения других способов динамического именования переменных и почему это обычно не очень хорошая идея см. этот блог пост.
да, сам утомительно. Но разве это лучше?
class Test: def __init__(_): _.test = 'test' def run(_): print _.test
на самом деле вы можете использовать рецепт "Implicit self" из презентации Армина Ронахера "5 лет плохих идей" ( google it).
Это очень умный рецепт, как и почти все от Армина Ронахера, но я не думаю, что эта идея очень привлекательна. Я думаю, что я бы предпочел явный этой в C# / Java.
обновление. Ссылка на "рецепт плохой идеи":https://speakerdeck.com/mitsuhiko/5-years-of-bad-ideas?slide=58
от: Self Hell-более статусные функции.
...гибридный подход работает лучше всего. Все ваши методы класса, которые на самом деле do вычисление должно быть перемещено в замыкания, а расширения для очистки синтаксиса должны храниться в классах. Поместите замыкания в классы, рассматривая класс так же, как пространство имен. Замыкания по существу являются статическими функциями и поэтому не требуют selfs*, даже в классе...
Comments