質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.64%

関数isinstanceでエラーが出てしまいます。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 450

epipy

score 11

 問題点

エラーが出てしまうのは、ソースコードの下から3行の部分(print部分)です。

順に、
Buzz Aldrin is a student is True
Billy Beaver is a student is True
Billy Bob Beaver is a student is False
と返すみたいなのですが、
print(p5, 'is a student is', p5.isStudent()) 
AttributeError: 'Grad' object has no attribute 'isStudent'
というエラーが出てしまいます。

私の考えでは、
isStudent(p5, Student)で、type(p5) == Student を判定するとTrueを返すという結果になると思っていました。

ご教授の程宜しくお願いします。

 該当のソースコード

class Person(object):

    def __init__(self, name):
        """"「人間」を形成する"""
        self.name = name #selfにname(入力)を代入する
        try:
            lastBlank = name.rindex(' ') #lastBlankにnameの空白の後ろからの位置番号を代入
                                         #rindex()は()を後ろから探したときの出現位置を返す
            self.lastName = name[lastBlank + 1:] #姓をself.lastNameに代入
        except: #空白が見つからないとき
            self.lastName = name
        self.birthday = None #初期化

    def getName(self):
        """selfの名前(フルネーム)を返す"""
        return self.name

    def getLastName(self):
        """selfの姓を返す"""
        return self.lastName

    def setBirthday(self, birthdate):
        """birthdateをdatetime.date型とする
           selfの生年月日をbirthdateと設定する"""
        self.birthday = birthdate

    def getAge(self):
        """selfの現在の年齢を日単位で返す"""
        if self.birthday==None:
            raise ValueError
        return (datetime.date.today() - self.birthday).days #今日の日付-誕生日 (.daysで日に換算)

    def __lt__(self, other):
        """selfの名前がotherの名前と比べて
           アルファベット順で前ならばTrueを、
           そうでなければFalseを返す
           比較は、姓について行われるが、
           姓が同じであれば名前(フルネーム)が比較される"""
        if self.lastName==other.lastName: #selfの姓がotherの姓とは同じ場合
            return self.name < other.name #フルネームの比較に入る
        return self.lastName < other.lastName #selfの名前がotherの名前と比べてアルファベット順で前

    def __str__(self):
        """selfの名前(フルネーム)を返す"""
        return self.name


class MITPerson(Person): #属性の継承

    nextIdNum = 0 #個人識別番号

    def __init__(self, name):
        Person.__init__(self, name) #Personの中のinitを参照
        self.idNum = MITPerson.nextIdNum #selfのidNumに、MITPersonのnextIdNumを代入する
        MITPerson.nextIdNum += 1 #MITPersonのnextIdNumを1増やす

    def getIdNum(self):
        return self.idNum

    def __lt__(self, other):
        return self.idNum < other.idNum

p1 = MITPerson('Mark Guttag')
p2 = MITPerson('Billy Bob Beaver')
p3 = MITPerson('Billy Bob Beaver')
p4 = Person('Billy Bob Beaver')


class Student(MITPerson): #MITPerson/Student
    pass
class UG(Student): #Student/UG ,UGはStudentのサブクラス
    def __init__(self, name, classYear):
        MITPerson.__init__(self, name)
        self.year = classYear
    def getClass(self):
        return self.year
class Grad(Student): #Student/Grad
    pass


p5 = Grad('Buzz Aldrin') #Student型
p6 = UG('Billy Beaver', 1984) #UG型のオブジェクト(書き方により__init__に行く?)が結び付けられている
print(p5, 'is a graduate student is', type(p5)==Grad)
print(p5, 'is an undergraduate student is', type(p5)==UG)


def isStudent(self):
    return isinstance(self, Student) #instance(引数1, 引数2)
                                     #1番目の引数が2番目の引数で示された方の
                                     #インスタンスであるときTrue

print(p5, 'is a student is', p5.isStudent()) #instance(p5, Student) , selfにはp5自身が入る
print(p6, 'is a student is', p6.isStudent()) #p6が結び付けられているオブジェクトはUG型
                                             #ただし、UGはStudentのサブクラスであるので
                                             #クラスStudentのインスタンスであるともみなされる。
print(p3, 'is a student is', p3.isStudent())

 試したこと

'#'を用いて3つの行、全て独立に実行してみたのですが3つの行ともどれもエラーを吐き出してしまいました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

isStudentのインデントレベルが浅いせいで、一般の関数だと思われています。

class Grad(Student):
    # これはメソッド
    def isStudent(self):
        ...
class Grad(Student):
    ...

# これは関数
def isStudent(self):
    ...

もちろん間にあるスクリプトコードは適切な位置に移動してやる必要があります。


関数isinstanceでエラーが出てしまいます。

エラーメッセージを読むと、本当の原因が分かります。

AttributeError: 'Grad' object has no attribute 'isStudent'

isinstanceの使い方に直接起因するエラーではありません。
isStudentがGradに結び付いていない(attributeではない)ことが問題なのです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/23 13:13

    インデントレベルの話を完全に忘れていました。
    エラーメッセージがどういう意味を表しているか、確実にくみ取ることが重要ですね。
    迅速なご回答ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る