IDE nie widzi zadeklarowanego parametru "self"

IDE nie widzi zadeklarowanego parametru "self"
Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Witam. Niedawno rozpocząłem naukę programowania i postanowiłem zacząć od Pythona, ponieważ czytałem że jest najprostszy i rzeczywiście taki jest. Po pewnych zagadnieniach przyszedł czas na obiektówkę, postanowiłem nauczyć się klas,obiektów, metod itd. Skorzystałem z kursu na yt i śledziłem poczynania gościa który pisał program, który wykorzystywał obiektówke. Zadaniem tego programu było stworzyć klasę "Zwierze" dać mu parametry: Imie, Wysokosc, Waga i Dzwiek jaki wydaje, pozniej natomiast owy obiekt mial sie przedstawic czyli pwoeidziec jak sie nazywa, ile ma wzrostu, wagi itd po stworzeniu go w sposob np

Kopiuj
Kot = Zwierze('Puszek',10,5,'Miau')
print(Kot.NazwaTamtejFunkcjiKtoraMialaWypisywac())

wszystko fajnie, jednak zanim do tego doszedłem napotkałem u siebie błąd:

Kopiuj
class Animal:
	__name =  ""
	__height = 0
	__weight = 0
	__sound = 0

	def __init__(self,name,height,weight,sound):
		self.__name = name
		self.__height = height
		self.__weight = weight
		self.__sound = sound

	def set_name(self, name):
        self.__name = name   # <---------- w tym miejscu IDE nie znajduje mi podanego wczesniej 'self.__name' ani samego 'name'

    def get_name(self):
        return self.__name
 

Chciałbym wiedzieć co schrzaniłem i później nie popełniać takich błędów. Z góry dziękuję bardzo za pomoc :)

2

Masz głupie IDE i tyle. Korzystaj z darmowego PyCharm Community.

Co do kodu to kilka uwag:

  1. Po co tworzyć statyczne skoro żaden obiekt z nich nie skorzysta? W init te dane są nadpisywane dla każdego egzemplarza.
  2. set_name, get_name na takich durnych przykładach się nie opłaca - bo niby czemu później masz używać animal.get_name() zamiast animal.name? Nim mądrze zaczniesz używać hermetyzacji miną wieki. W każdym razie nie wszędzie opłaca się robić akcesory/gettery.

PS, polecam zmienić kurs z którego uczysz się pythona.

TH
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:35
4

W Pythonie wszystko jest publiczne, nie powinieneś pól klasy tworzyć w ten sposób. Python dodaje do nich nazwę klasy, tym samym u Ciebie "imię" zwierzaka wygląda dokładnie tak: "_Animal__name" i dlatego self nie widzi atrybutu "__name". Możesz to sprawdzić w konsoli pythona, po zaimportowaniu klasy, stwórz obiekt klasy Animal i wywołaj na nim funkcję:

dir(zwierzak)

W odpowiedzi dostaniesz, coś podobnego do:

['_Animal__name', '__doc__', '__init__', '__module__']

Jeżeli chcesz oznaczyć dany atrybut lub metodę, że jest prywatna, to dodawaj do niej jedno podkreślenie "_name". Python wtedy nie dodaje nazwy klasy na początku. Atrybut jest jednak publiczny. Zapytasz więc, po co takie coś? Ano dlatego, że jak ktoś będzie chciał zrobić "zwierzak.sound", to mu się to nie uda, bo u Ciebie będzie _sound, o którym Ty jako programista wiesz. Po drugie dodanie jednego podkreślenia jest informacją dla innych programistów, że dany atrybut czy też metoda są prywatne, a działanie Twojej klasy i metod pozostaje zgodne z filozofią Pythona.

Twój kod może wyglądać w ten sposób:

Kopiuj
 
class Animal:
 
    def __init__(self,name,height,weight,sound):
        self._name = name
        self._height = height
        self._weight = weight
        self._sound = sound
 
    def set_name(self, name):
        self._name = name
 
    def get_name(self):
        return self._name

A jeszcze lepiej jak użyjesz @property:

Kopiuj
 
class Animal(object):
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @x.setter
    def x(self, name):
        self._name = name

To jest właściwy sposób tworzenia setterów i getterów w Pythonie. Dzięki temu zamiast pisać "zwierzak.set_name('imie')", piszesz "zwierzak.name = 'imie'", a zamiast zwierzak.get_name()" zwyczajnie "zwierzak.name".

edytowany 2x, ostatnio: Thyliamris
AD
Dobrze wytłumaczone, mi też się przyda ;)
G3
@Thyliamris Nie masz racji, wprowadzasz w błąd. Metoda, zmienna prywatna jest w "normalny" sposób dostępna z klasy w której została zdefiniowana.
TH
@grzgrzgrz3, nie bardzo rozumiem, gdzie wprowadzam w błąd... Jeśli metoda zaczyna się od podwójnego podkreślenia, to do nazwy metody dodawana jest nazwa klasy. Oczywiście, że jest do niej dostęp (co zaznaczyłem na wstępie, że w Pythonie wszystko jest publiczne), ale trzeba dopisać nazwę klasy. Jeśli zaś nazwa metody rozpoczyna się od jednego podkreślenia, to jest dostępna normalnie przez swoją nazwę, a jej prywatność jest umowna - co też zaznaczyłem w tekście. Wskaż gdzie jest błąd. http://stackoverflow.com/a/6930223/2078567
G3
Napisałem Ci wyżej gdzie jest błąd. Metoda z double leading underscore (prywatna) z poziomu klasy gdzie została zdefiniowana jest dostępna bez podawania self._NazwaKlasy__moja_metoda, tylko self.__moja_metoda .
TH
Masz rację - wewnątrz tej samej klasy jest widoczna. Ale jeśli zrobisz dziedziczenie po tej klasie i będziesz chciał się odwołać do tego atrybutu wewnątrz nowej klasy, to już tego nie zrobisz.
Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Korzystam z JetBrains PyCharm 5.0.3
Rozumiem. Gosc na kursie na yt zagmatwał, a że ja nie mam doświadczenia w pisaniu obiektowym nie połapałem się o co w tym chodzi.

Mam jeszcze takie pytanie. Czy jak chce pisac takie wieksze programy z wykorzystaniem obiektu to musze wykorzystywac konsole Pythona ? Nie korzystalem z tego, zwykle pisalem w środowisku i po odpaleniu wyświetlał mi się wynik pod kodem w takiej środowiskowej konsoli.

Dzieki za odpowiedzi, musze jeszcze poznac wiele rzeczy..

Wizzie
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 7 lat
0

Ta "srodowiskowa konsola" to jest to samo co konsola typu "cmd" w windowsie, tylko, że wsadzili ją w IDE, żeby było wygodniej. Jak wywołasz to w cmd to dostaniesz to samo.

Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Juz nie wiem o co chodzi, zdaje sie ze zupelnie nie rozumiem programowania obiektowego

Kopiuj
class Pies:
	def _init_(self,imie):
		self.imie = imie
	def _str_(self):
		rep = "Obiekt klasy Pies\n"
		rep += "imie: ",self.imie,"\n"
		return rep

	def Szczekaj(self):
		print("Hau!Hau! Jestem ",self.imie,"\n")

pies1 = Pies("Jamnik")

pies1.Szczekaj()
 

W zalozeniu jest zeby Wyswietlilo mi: Hau!Hau! Jestem Jamnik
a zamiast tego wyswietla:

Kopiuj
Traceback (most recent call last):
  File "C:/Users/Neapol/Desktop/wonsz/pierwszy.py", line 13, in <module>
    pies1 = Pies("Jamnik")
TypeError: object() takes no parameters

Obiekt nie posiada parametrów? Ale przeciez podałem parametr "Jamnik" jako imie. Czego brakuje? Pomoze mi ktos? :(

0

Masz jeden (a właściwie dwa) malutki(e) błąd (błędy) na początku klasy (przy init).

Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

mówisz o konstruktorze który nie jest publiczny ? niestety kiedy dam __init__ wynik jest identyczny, dziwne bo ludziom w kursach te rzeczy chodzą. trzeba do obiektowego importować jakiś moduł ??

edytowany 1x, ostatnio: Neapol
0

Dziwne, bo w IDLE działa poprawnie.

Kopiuj
class Pies:
    def __init__(self,imie):
        self.imie = imie
    def __str__(self):
        rep = "Obiekt klasy Pies\n"
        rep += "imie: " + self.imie + "\n"
        #wyżej mała zmiana, pierwotna wersja poprawnie nie działa.
        return rep
 
    def Szczekaj(self):
        print("Hau!Hau! Jestem ",self.imie,"\n")
 
pies1 = Pies("Jamnik")
 
pies1.Szczekaj() 
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Zmyślasz, http://ideone.com/GBgirB
Jak uruchamiasz kod po zmianie

Kopiuj
_init_
#na
__init__

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

nie zmyślam. czy jest problem z moim środowiskiem ? user image

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
2

Zmyślasz, nie zmieniłeś _init_ na __init__.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

okej. wczesniej probowalem i nie dawalo mi wyniku jaki chcialem, kiedy dawalem 2 podkreslenia. widac coś innego wcześniej miałem źle. przepraszam za zamieszanie, to przez moje gapiostwo. dzięki za pomoc :)

edytowany 1x, ostatnio: Neapol
2

To w takim razie następna lekcja, bo widzę, że zacząłeś stosować pojedyncze podkreślenia w nazwach funkcji. W Pythonie obecne są specjalne, wbudowane w język funkcje. Nie trzeba ich samemu pisac, po prostu są i dla wyróżnienia pisane są z dwoma podkreśleniami na początku i dwoma a z tyłu. Należą do nich właśnie __init__, __dict__, __repr__ itp. Tutaj zasada jednego podkreślenia nie jest stosowana :) Aczkolwiek deklarując własną metodę możesz jej nazwę rozpocząć jednym podkreśleniem, np:

Kopiuj
 
def _moja_prywatna_metoda(self):
  return self.name

Tutaj zasada jest taka sama jak przy atrybutach klasy: metoda z jednym podkreśleniem jest tylko umownie prywatna.

0

Najnowszy Notepad++ ma również dobry system podpowiedzi do Pythona.

Shalom
A lodówki i mikrofalówki mają teraz wifi, co nie znaczy jednak że należy ich uzywać jako podstawowe narzędzia do przeglądania stron www ;]
Neapol
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Dzięki dobrzy ludzie. Nie zapomnę. I przepraszam za taki spam z tak trywialnego powodu :)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)